| 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 <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 | 542 |
| 543 template <typename T> | 543 template <typename T> |
| 544 class StrictNumeric; | 544 class StrictNumeric; |
| 545 | 545 |
| 546 // Used to treat CheckedNumeric and arithmetic underlying types the same. | 546 // Used to treat CheckedNumeric and arithmetic underlying types the same. |
| 547 template <typename T> | 547 template <typename T> |
| 548 struct UnderlyingType { | 548 struct UnderlyingType { |
| 549 using type = typename ArithmeticOrUnderlyingEnum<T>::type; | 549 using type = typename ArithmeticOrUnderlyingEnum<T>::type; |
| 550 static const bool is_numeric = std::is_arithmetic<type>::value; | 550 static const bool is_numeric = std::is_arithmetic<type>::value; |
| 551 static const bool is_checked = false; | 551 static const bool is_checked = false; |
| 552 static const bool is_clamped = false; |
| 552 static const bool is_strict = false; | 553 static const bool is_strict = false; |
| 553 }; | 554 }; |
| 554 | 555 |
| 555 template <typename T> | 556 template <typename T> |
| 556 struct UnderlyingType<CheckedNumeric<T>> { | 557 struct UnderlyingType<CheckedNumeric<T>> { |
| 557 using type = T; | 558 using type = T; |
| 558 static const bool is_numeric = true; | 559 static const bool is_numeric = true; |
| 559 static const bool is_checked = true; | 560 static const bool is_checked = true; |
| 560 static const bool is_clamped = false; | 561 static const bool is_clamped = false; |
| 561 static const bool is_strict = false; | 562 static const bool is_strict = false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 583 struct IsCheckedOp { | 584 struct IsCheckedOp { |
| 584 static const bool value = | 585 static const bool value = |
| 585 UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && | 586 UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && |
| 586 (UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked); | 587 (UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked); |
| 587 }; | 588 }; |
| 588 | 589 |
| 589 template <typename L, typename R> | 590 template <typename L, typename R> |
| 590 struct IsClampedOp { | 591 struct IsClampedOp { |
| 591 static const bool value = | 592 static const bool value = |
| 592 UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && | 593 UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && |
| 593 (UnderlyingType<L>::is_clamped || UnderlyingType<R>::is_clamped); | 594 (UnderlyingType<L>::is_clamped || UnderlyingType<R>::is_clamped) && |
| 595 !(UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked); |
| 594 }; | 596 }; |
| 595 | 597 |
| 596 template <typename L, typename R> | 598 template <typename L, typename R> |
| 597 struct IsStrictOp { | 599 struct IsStrictOp { |
| 598 static const bool value = | 600 static const bool value = |
| 599 UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && | 601 UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && |
| 600 (UnderlyingType<L>::is_strict || UnderlyingType<R>::is_strict); | 602 (UnderlyingType<L>::is_strict || UnderlyingType<R>::is_strict) && |
| 603 !(UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked) && |
| 604 !(UnderlyingType<L>::is_clamped || UnderlyingType<R>::is_clamped); |
| 601 }; | 605 }; |
| 602 | 606 |
| 603 template <typename L, typename R> | 607 template <typename L, typename R> |
| 604 constexpr bool IsLessImpl(const L lhs, | 608 constexpr bool IsLessImpl(const L lhs, |
| 605 const R rhs, | 609 const R rhs, |
| 606 const RangeCheck l_range, | 610 const RangeCheck l_range, |
| 607 const RangeCheck r_range) { | 611 const RangeCheck r_range) { |
| 608 return l_range.IsUnderflow() || r_range.IsOverflow() || | 612 return l_range.IsUnderflow() || r_range.IsOverflow() || |
| 609 (l_range == r_range && | 613 (l_range == r_range && |
| 610 static_cast<decltype(lhs + rhs)>(lhs) < | 614 static_cast<decltype(lhs + rhs)>(lhs) < |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 static_cast<BigType>(static_cast<L>(lhs)), | 726 static_cast<BigType>(static_cast<L>(lhs)), |
| 723 static_cast<BigType>(static_cast<R>(rhs))) | 727 static_cast<BigType>(static_cast<R>(rhs))) |
| 724 // Let the template functions figure it out for mixed types. | 728 // Let the template functions figure it out for mixed types. |
| 725 : C<L, R>::Test(lhs, rhs); | 729 : C<L, R>::Test(lhs, rhs); |
| 726 } | 730 } |
| 727 | 731 |
| 728 } // namespace internal | 732 } // namespace internal |
| 729 } // namespace base | 733 } // namespace base |
| 730 | 734 |
| 731 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 735 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
| OLD | NEW |