OLD | NEW |
---|---|
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_CONVERSIONS_IMPL_H_ | 5 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
6 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 6 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
7 | 7 |
8 #include <limits.h> | 8 #include <limits.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, | 328 static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, |
329 size_t>::type value = | 329 size_t>::type value = |
330 CHAR_BIT * sizeof(Integer) - 1; | 330 CHAR_BIT * sizeof(Integer) - 1; |
331 }; | 331 }; |
332 | 332 |
333 enum ArithmeticPromotionCategory { | 333 enum ArithmeticPromotionCategory { |
334 LEFT_PROMOTION, // Use the type of the left-hand argument. | 334 LEFT_PROMOTION, // Use the type of the left-hand argument. |
335 RIGHT_PROMOTION // Use the type of the right-hand argument. | 335 RIGHT_PROMOTION // Use the type of the right-hand argument. |
336 }; | 336 }; |
337 | 337 |
338 template <ArithmeticPromotionCategory Promotion, | 338 // Determines the type that can represent the largest positive value. |
339 typename Lhs, | |
340 typename Rhs = Lhs> | |
341 struct ArithmeticPromotion; | |
342 | |
343 template <typename Lhs, | 339 template <typename Lhs, |
344 typename Rhs, | 340 typename Rhs, |
345 ArithmeticPromotionCategory Promotion = | 341 ArithmeticPromotionCategory Promotion = |
346 (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) | 342 (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) |
347 ? LEFT_PROMOTION | 343 ? LEFT_PROMOTION |
348 : RIGHT_PROMOTION> | 344 : RIGHT_PROMOTION> |
349 struct MaxExponentPromotion; | 345 struct MaxExponentPromotion; |
350 | 346 |
351 template <typename Lhs, typename Rhs> | 347 template <typename Lhs, typename Rhs> |
352 struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION> { | 348 struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION> { |
353 using type = Lhs; | 349 using type = Lhs; |
354 }; | 350 }; |
355 | 351 |
356 template <typename Lhs, typename Rhs> | 352 template <typename Lhs, typename Rhs> |
357 struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION> { | 353 struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION> { |
358 using type = Rhs; | 354 using type = Rhs; |
359 }; | 355 }; |
360 | 356 |
357 // Determines the type that can represent the lowest arithmetic value. | |
dcheng
2016/12/03 21:34:29
Nit: it kind of feels like we should be more consi
jschuh
2016/12/03 22:29:12
I tried to be consistent with std::numeric_limits<
| |
358 template <typename Lhs, | |
359 typename Rhs, | |
360 ArithmeticPromotionCategory Promotion = | |
361 std::is_signed<Lhs>::value | |
362 ? (std::is_signed<Rhs>::value | |
363 ? (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value | |
364 ? LEFT_PROMOTION | |
365 : RIGHT_PROMOTION) | |
366 : LEFT_PROMOTION) | |
367 : (std::is_signed<Rhs>::value | |
368 ? RIGHT_PROMOTION | |
369 : (MaxExponent<Lhs>::value < MaxExponent<Rhs>::value | |
370 ? LEFT_PROMOTION | |
371 : RIGHT_PROMOTION))> | |
372 struct LowestValuePromotion; | |
373 | |
374 template <typename Lhs, typename Rhs> | |
375 struct LowestValuePromotion<Lhs, Rhs, LEFT_PROMOTION> { | |
376 using type = Lhs; | |
377 }; | |
378 | |
379 template <typename Lhs, typename Rhs> | |
380 struct LowestValuePromotion<Lhs, Rhs, RIGHT_PROMOTION> { | |
381 using type = Rhs; | |
382 }; | |
383 | |
384 // Determines the type that is best able to represent an arithmetic result. | |
361 template <typename Lhs, | 385 template <typename Lhs, |
362 typename Rhs = Lhs, | 386 typename Rhs = Lhs, |
363 bool is_intmax_type = | 387 bool is_intmax_type = |
364 std::is_integral< | 388 std::is_integral< |
365 typename MaxExponentPromotion<Lhs, Rhs>::type>::value && | 389 typename MaxExponentPromotion<Lhs, Rhs>::type>::value && |
366 sizeof(typename MaxExponentPromotion<Lhs, Rhs>::type) == | 390 sizeof(typename MaxExponentPromotion<Lhs, Rhs>::type) == |
367 sizeof(intmax_t), | 391 sizeof(intmax_t), |
368 bool is_max_exponent = | 392 bool is_max_exponent = |
369 StaticDstRangeRelationToSrcRange< | 393 StaticDstRangeRelationToSrcRange< |
370 typename MaxExponentPromotion<Lhs, Rhs>::type, | 394 typename MaxExponentPromotion<Lhs, Rhs>::type, |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 static_cast<BigType>(static_cast<L>(lhs)), | 642 static_cast<BigType>(static_cast<L>(lhs)), |
619 static_cast<BigType>(static_cast<R>(rhs))) | 643 static_cast<BigType>(static_cast<R>(rhs))) |
620 // Let the template functions figure it out for mixed types. | 644 // Let the template functions figure it out for mixed types. |
621 : C<L, R>::Test(lhs, rhs); | 645 : C<L, R>::Test(lhs, rhs); |
622 }; | 646 }; |
623 | 647 |
624 } // namespace internal | 648 } // namespace internal |
625 } // namespace base | 649 } // namespace base |
626 | 650 |
627 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 651 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
OLD | NEW |