bounds.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. use core::{usize, u8, u16, u32, u64};
  2. use core::{isize, i8, i16, i32, i64};
  3. use core::{f32, f64};
  4. use core::num::Wrapping;
  5. #[cfg(has_i128)]
  6. use core::{i128, u128};
  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 { $min }
  20. #[inline]
  21. fn max_value() -> $t { $max }
  22. }
  23. }
  24. }
  25. bounded_impl!(usize, usize::MIN, usize::MAX);
  26. bounded_impl!(u8, u8::MIN, u8::MAX);
  27. bounded_impl!(u16, u16::MIN, u16::MAX);
  28. bounded_impl!(u32, u32::MIN, u32::MAX);
  29. bounded_impl!(u64, u64::MIN, u64::MAX);
  30. #[cfg(has_i128)]
  31. bounded_impl!(u128, u128::MIN, u128::MAX);
  32. bounded_impl!(isize, isize::MIN, isize::MAX);
  33. bounded_impl!(i8, i8::MIN, i8::MAX);
  34. bounded_impl!(i16, i16::MIN, i16::MAX);
  35. bounded_impl!(i32, i32::MIN, i32::MAX);
  36. bounded_impl!(i64, i64::MIN, i64::MAX);
  37. #[cfg(has_i128)]
  38. bounded_impl!(i128, i128::MIN, i128::MAX);
  39. impl<T: Bounded> Bounded for Wrapping<T> {
  40. fn min_value() -> Self { Wrapping(T::min_value()) }
  41. fn max_value() -> Self { Wrapping(T::max_value()) }
  42. }
  43. bounded_impl!(f32, f32::MIN, f32::MAX);
  44. macro_rules! for_each_tuple_ {
  45. ( $m:ident !! ) => (
  46. $m! { }
  47. );
  48. ( $m:ident !! $h:ident, $($t:ident,)* ) => (
  49. $m! { $h $($t)* }
  50. for_each_tuple_! { $m !! $($t,)* }
  51. );
  52. }
  53. macro_rules! for_each_tuple {
  54. ( $m:ident ) => (
  55. for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
  56. );
  57. }
  58. macro_rules! bounded_tuple {
  59. ( $($name:ident)* ) => (
  60. impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
  61. #[inline]
  62. fn min_value() -> Self {
  63. ($($name::min_value(),)*)
  64. }
  65. #[inline]
  66. fn max_value() -> Self {
  67. ($($name::max_value(),)*)
  68. }
  69. }
  70. );
  71. }
  72. for_each_tuple!(bounded_tuple);
  73. bounded_impl!(f64, f64::MIN, f64::MAX);
  74. #[test]
  75. fn wrapping_bounded() {
  76. macro_rules! test_wrapping_bounded {
  77. ($($t:ty)+) => {
  78. $(
  79. assert_eq!(Wrapping::<$t>::min_value().0, <$t>::min_value());
  80. assert_eq!(Wrapping::<$t>::max_value().0, <$t>::max_value());
  81. )+
  82. };
  83. }
  84. test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  85. }
  86. #[cfg(has_i128)]
  87. #[test]
  88. fn wrapping_bounded_i128() {
  89. macro_rules! test_wrapping_bounded {
  90. ($($t:ty)+) => {
  91. $(
  92. assert_eq!(Wrapping::<$t>::min_value().0, <$t>::min_value());
  93. assert_eq!(Wrapping::<$t>::max_value().0, <$t>::max_value());
  94. )+
  95. };
  96. }
  97. test_wrapping_bounded!(u128 i128);
  98. }
  99. #[test]
  100. fn wrapping_is_bounded() {
  101. fn require_bounded<T: Bounded>(_: &T) {}
  102. require_bounded(&Wrapping(42_u32));
  103. require_bounded(&Wrapping(-42));
  104. }