Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: base/numerics/safe_math_impl.h

Issue 1346753002: Implement CheckedNumeric::UnsignedAbs() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: gcc build fix Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/numerics/safe_math.h ('k') | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_ 5 #ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_
6 #define BASE_NUMERICS_SAFE_MATH_IMPL_H_ 6 #define BASE_NUMERICS_SAFE_MATH_IMPL_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <cmath> 10 #include <cmath>
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 sizeof(Integer) * 2, 83 sizeof(Integer) * 2,
84 std::numeric_limits<Integer>::is_signed>::type>::type type; 84 std::numeric_limits<Integer>::is_signed>::type>::type type;
85 }; 85 };
86 86
87 template <typename Integer> 87 template <typename Integer>
88 struct PositionOfSignBit { 88 struct PositionOfSignBit {
89 static const typename enable_if<std::numeric_limits<Integer>::is_integer, 89 static const typename enable_if<std::numeric_limits<Integer>::is_integer,
90 size_t>::type value = 8 * sizeof(Integer) - 1; 90 size_t>::type value = 8 * sizeof(Integer) - 1;
91 }; 91 };
92 92
93 // This is used for UnsignedAbs, where we need to support floating-point
94 // template instantiations even though we don't actually support the operations.
95 // However, there is no corresponding implementation of e.g. CheckedUnsignedAbs,
96 // so the float versions will not compile.
97 template <typename Numeric,
98 bool IsInteger = std::numeric_limits<Numeric>::is_integer,
99 bool IsFloat = std::numeric_limits<Numeric>::is_iec559>
100 struct UnsignedOrFloatForSize;
101
102 template <typename Numeric>
103 struct UnsignedOrFloatForSize<Numeric, true, false> {
104 typedef typename UnsignedIntegerForSize<Numeric>::type type;
105 };
106
107 template <typename Numeric>
108 struct UnsignedOrFloatForSize<Numeric, false, true> {
109 typedef Numeric type;
110 };
111
93 // Helper templates for integer manipulations. 112 // Helper templates for integer manipulations.
94 113
95 template <typename T> 114 template <typename T>
96 bool HasSignBit(T x) { 115 bool HasSignBit(T x) {
97 // Cast to unsigned since right shift on signed is undefined. 116 // Cast to unsigned since right shift on signed is undefined.
98 return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >> 117 return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >>
99 PositionOfSignBit<T>::value); 118 PositionOfSignBit<T>::value);
100 } 119 }
101 120
102 // This wrapper undoes the standard integer promotions. 121 // This wrapper undoes the standard integer promotions.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 *validity = 296 *validity =
278 value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; 297 value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
279 return static_cast<T>(std::abs(value)); 298 return static_cast<T>(std::abs(value));
280 } 299 }
281 300
282 template <typename T> 301 template <typename T>
283 typename enable_if< 302 typename enable_if<
284 std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, 303 std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
285 T>::type 304 T>::type
286 CheckedAbs(T value, RangeConstraint* validity) { 305 CheckedAbs(T value, RangeConstraint* validity) {
287 // Absolute value of a positive is just its identiy. 306 // T is unsigned, so |value| must already be positive.
288 *validity = RANGE_VALID; 307 *validity = RANGE_VALID;
289 return value; 308 return value;
290 } 309 }
291 310
311 template <typename T>
312 typename enable_if<std::numeric_limits<T>::is_integer &&
313 std::numeric_limits<T>::is_signed,
314 typename UnsignedIntegerForSize<T>::type>::type
315 CheckedUnsignedAbs(T value) {
316 typedef typename UnsignedIntegerForSize<T>::type UnsignedT;
317 return value == std::numeric_limits<T>::min()
318 ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1
319 : static_cast<UnsignedT>(std::abs(value));
320 }
321
322 template <typename T>
323 typename enable_if<std::numeric_limits<T>::is_integer &&
324 !std::numeric_limits<T>::is_signed,
325 T>::type
326 CheckedUnsignedAbs(T value) {
327 // T is unsigned, so |value| must already be positive.
328 return value;
329 }
330
292 // These are the floating point stubs that the compiler needs to see. Only the 331 // These are the floating point stubs that the compiler needs to see. Only the
293 // negation operation is ever called. 332 // negation operation is ever called.
294 #define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ 333 #define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \
295 template <typename T> \ 334 template <typename T> \
296 typename enable_if<std::numeric_limits<T>::is_iec559, T>::type \ 335 typename enable_if<std::numeric_limits<T>::is_iec559, T>::type \
297 Checked##NAME(T, T, RangeConstraint*) { \ 336 Checked##NAME(T, T, RangeConstraint*) { \
298 NOTREACHED(); \ 337 NOTREACHED(); \
299 return 0; \ 338 return 0; \
300 } 339 }
301 340
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 sizeof(T) >= (2 * sizeof(Lhs)) && 531 sizeof(T) >= (2 * sizeof(Lhs)) &&
493 StaticDstRangeRelationToSrcRange<T, Rhs>::value != 532 StaticDstRangeRelationToSrcRange<T, Rhs>::value !=
494 NUMERIC_RANGE_CONTAINED && 533 NUMERIC_RANGE_CONTAINED &&
495 sizeof(T) >= (2 * sizeof(Rhs)); 534 sizeof(T) >= (2 * sizeof(Rhs));
496 }; 535 };
497 536
498 } // namespace internal 537 } // namespace internal
499 } // namespace base 538 } // namespace base
500 539
501 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ 540 #endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_
OLDNEW
« no previous file with comments | « base/numerics/safe_math.h ('k') | base/numerics/safe_numerics_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698