bounds.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. /// Numbers which have lower bounds
  16. pub trait LowerBounded {
  17. /// Returns the smallest finite number this type can represent
  18. fn min_value() -> Self;
  19. }
  20. // FIXME: With a major version bump, this should be a supertrait instead
  21. impl<T: Bounded> LowerBounded for T {
  22. fn min_value() -> T {
  23. Bounded::min_value()
  24. }
  25. }
  26. /// Numbers which have upper bounds
  27. pub trait UpperBounded {
  28. /// Returns the largest finite number this type can represent
  29. fn max_value() -> Self;
  30. }
  31. // FIXME: With a major version bump, this should be a supertrait instead
  32. impl<T: Bounded> UpperBounded for T {
  33. fn max_value() -> T {
  34. Bounded::max_value()
  35. }
  36. }
  37. macro_rules! bounded_impl {
  38. ($t:ty, $min:expr, $max:expr) => {
  39. impl Bounded for $t {
  40. #[inline]
  41. fn min_value() -> $t {
  42. $min
  43. }
  44. #[inline]
  45. fn max_value() -> $t {
  46. $max
  47. }
  48. }
  49. };
  50. }
  51. bounded_impl!(usize, usize::MIN, usize::MAX);
  52. bounded_impl!(u8, u8::MIN, u8::MAX);
  53. bounded_impl!(u16, u16::MIN, u16::MAX);
  54. bounded_impl!(u32, u32::MIN, u32::MAX);
  55. bounded_impl!(u64, u64::MIN, u64::MAX);
  56. #[cfg(has_i128)]
  57. bounded_impl!(u128, u128::MIN, u128::MAX);
  58. bounded_impl!(isize, isize::MIN, isize::MAX);
  59. bounded_impl!(i8, i8::MIN, i8::MAX);
  60. bounded_impl!(i16, i16::MIN, i16::MAX);
  61. bounded_impl!(i32, i32::MIN, i32::MAX);
  62. bounded_impl!(i64, i64::MIN, i64::MAX);
  63. #[cfg(has_i128)]
  64. bounded_impl!(i128, i128::MIN, i128::MAX);
  65. impl<T: Bounded> Bounded for Wrapping<T> {
  66. fn min_value() -> Self {
  67. Wrapping(T::min_value())
  68. }
  69. fn max_value() -> Self {
  70. Wrapping(T::max_value())
  71. }
  72. }
  73. bounded_impl!(f32, f32::MIN, f32::MAX);
  74. macro_rules! for_each_tuple_ {
  75. ( $m:ident !! ) => (
  76. $m! { }
  77. );
  78. ( $m:ident !! $h:ident, $($t:ident,)* ) => (
  79. $m! { $h $($t)* }
  80. for_each_tuple_! { $m !! $($t,)* }
  81. );
  82. }
  83. macro_rules! for_each_tuple {
  84. ($m:ident) => {
  85. for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
  86. };
  87. }
  88. macro_rules! bounded_tuple {
  89. ( $($name:ident)* ) => (
  90. impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
  91. #[inline]
  92. fn min_value() -> Self {
  93. ($($name::min_value(),)*)
  94. }
  95. #[inline]
  96. fn max_value() -> Self {
  97. ($($name::max_value(),)*)
  98. }
  99. }
  100. );
  101. }
  102. for_each_tuple!(bounded_tuple);
  103. bounded_impl!(f64, f64::MIN, f64::MAX);
  104. #[test]
  105. fn wrapping_bounded() {
  106. macro_rules! test_wrapping_bounded {
  107. ($($t:ty)+) => {
  108. $(
  109. assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
  110. assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
  111. )+
  112. };
  113. }
  114. test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
  115. }
  116. #[cfg(has_i128)]
  117. #[test]
  118. fn wrapping_bounded_i128() {
  119. macro_rules! test_wrapping_bounded {
  120. ($($t:ty)+) => {
  121. $(
  122. assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
  123. assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
  124. )+
  125. };
  126. }
  127. test_wrapping_bounded!(u128 i128);
  128. }
  129. #[test]
  130. fn wrapping_is_bounded() {
  131. fn require_bounded<T: Bounded>(_: &T) {}
  132. require_bounded(&Wrapping(42_u32));
  133. require_bounded(&Wrapping(-42));
  134. }