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); | |
dcheng
2017/06/28 07:25:06
This confused me a bit initially--why would we hav
jschuh
2017/06/28 12:32:38
I'll add it to the README. The gist is, if it can
| |
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 |