bounds.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. use core::num::Wrapping;
  2. use core::{f32, f64};
  3. #[cfg(has_i128)]
  4. use core::{i128, u128};
  5. use core::{i16, i32, i64, i8, isize};
  6. use core::{u16, u32, u64, u8, usize};
  7. /// Numbers which have upper and lower bounds
  8. pub trait Bounded {
  9. // FIXME (#5527): These should be associated constants
  10. /// returns the smallest finite number this type can represent
  11. fn min_value() -> Self;
  12. /// returns the largest finite number this type can represent
  13. fn max_value() -> Self;
  14. }
  15. macro_rules! bounded_impl {
  16. ($t:ty, $min:expr, $max:expr) => {
  17. impl Bounded for $t {
  18. #[inline]
  19. fn min_value() -> $t {
  20. $min
  21. }
  22. #[inline]
  23. fn max_value() -> $t {
  24. $max
  25. }
  26. }
  27. };
  28. }
  29. bounded_impl!(usize, usize::MIN, usize::MAX);
  30. bounded_impl!(u8, u8::MIN, u8::MAX);
  31. bounded_impl!(u16, u16::MIN, u16::MAX);
  32. bounded_impl!(u32, u32::MIN, u32::MAX);
  33. bounded_impl!(u64, u64::MIN, u64::MAX);
  34. #[cfg(has_i128)]
  35. bounded_impl!(u128, u128::MIN, u128::MAX);
  36. bounded_impl!(isize, isize::MIN, isize::MAX);
  37. bounded_impl!(i8, i8::MIN, i8::MAX);
  38. bounded_impl!(i16, i16::MIN, i16::MAX);
  39. bounded_impl!(i32, i32::MIN, i32::MAX);
  40. bounded_impl!(i64, i64::MIN, i64::MAX);
  41. #[cfg(has_i128)]
  42. bounded_impl!(i128, i128::MIN, i128::MAX);
  43. impl<T: Bounded> Bounded for Wrapping<T> {
  44. fn min_value() -> Self {
  45. Wrapping(T::min_value())
  46. }
  47. fn max_value() -> Self {
  48. Wrapping(T::max_value())
  49. }
  50. }
  51. bounded_impl!(f32, f32::MIN, f32::MAX);
  52. macro_rules! for_each_tuple_ {
  53. ( $m:ident !! ) => (
  54. $m! { }
  55. );
  56. ( $m:ident !! $h:ident, $($t:ident,)* ) => (
  57. $m! { $h $($t)* }
  58. for_each_tuple_! { $m !! $($t,)* }
  59. );
  60. }
  61. macro_rules! for_each_tuple {
  62. ($m:ident) => {
  63. for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
  64. };
  65. }
  66. macro_rules! bounded_tuple {
  67. ( $($name:ident)* ) => (
  68. impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
  69. #[inline]
  70. fn min_value() -> Self {
  71. ($($name::min_value(),)*)
  72. }
  73. #[inline]
  74. fn max_value() -> Self {
  75. ($($name::max_value(),)*)
  76. }
  77. }
  78. );
  79. }
  80. for_each_tuple!(bounded_tuple);
  81. bounded_impl!(f64, f64::MIN, f64::MAX);
  82. #[test]
  83. fn wrapping_bounded() {
  84. macro_rules! test_wrapping_bounded {
  85. ($($t:ty)+) => {
  86. $(
  87. assert_eq!(Wrapping::<$t>::min_value().0, <$t>::min_value());
  88. assert_eq!(Wrapping::<$t>::max_value().0, <$t>::max_value());
  89. )+
  90. };
  91. }
  92. test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  93. }
  94. #[cfg(has_i128)]
  95. #[test]
  96. fn wrapping_bounded_i128() {
  97. macro_rules! test_wrapping_bounded {
  98. ($($t:ty)+) => {
  99. $(
  100. assert_eq!(Wrapping::<$t>::min_value().0, <$t>::min_value());
  101. assert_eq!(Wrapping::<$t>::max_value().0, <$t>::max_value());
  102. )+
  103. };
  104. }
  105. test_wrapping_bounded!(u128 i128);
  106. }
  107. #[test]
  108. fn wrapping_is_bounded() {
  109. fn require_bounded<T: Bounded>(_: &T) {}
  110. require_bounded(&Wrapping(42_u32));
  111. require_bounded(&Wrapping(-42));
  112. }