|
1 | 1 | use core::num::Wrapping;
|
| 2 | +use core::num::{ |
| 3 | + NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, |
| 4 | + NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, |
| 5 | +}; |
2 | 6 | use core::{f32, f64};
|
3 | 7 | use core::{i128, i16, i32, i64, i8, isize};
|
4 | 8 | use core::{u128, u16, u32, u64, u8, usize};
|
@@ -68,6 +72,49 @@ bounded_impl!(i32, i32::MIN, i32::MAX);
|
68 | 72 | bounded_impl!(i64, i64::MIN, i64::MAX);
|
69 | 73 | bounded_impl!(i128, i128::MIN, i128::MAX);
|
70 | 74 |
|
| 75 | +macro_rules! bounded_impl_nonzero_const { |
| 76 | + ($t:ty, $v:expr, $i:ident) => { |
| 77 | + const $i: $t = { |
| 78 | + let arr = [$v]; |
| 79 | + let idx = if $v != 0 { 0 } else { 1 }; |
| 80 | + |
| 81 | + unsafe { <$t>::new_unchecked(arr[idx]) } |
| 82 | + }; |
| 83 | + }; |
| 84 | +} |
| 85 | + |
| 86 | +macro_rules! bounded_impl_nonzero { |
| 87 | + ($t:ty, $min:expr, $max:expr) => { |
| 88 | + impl Bounded for $t { |
| 89 | + #[inline] |
| 90 | + fn min_value() -> $t { |
| 91 | + bounded_impl_nonzero_const!($t, $min, MIN); |
| 92 | + MIN |
| 93 | + } |
| 94 | + |
| 95 | + #[inline] |
| 96 | + fn max_value() -> $t { |
| 97 | + bounded_impl_nonzero_const!($t, $max, MAX); |
| 98 | + MAX |
| 99 | + } |
| 100 | + } |
| 101 | + }; |
| 102 | +} |
| 103 | + |
| 104 | +bounded_impl_nonzero!(NonZeroUsize, 1, usize::MAX); |
| 105 | +bounded_impl_nonzero!(NonZeroU8, 1, u8::MAX); |
| 106 | +bounded_impl_nonzero!(NonZeroU16, 1, u16::MAX); |
| 107 | +bounded_impl_nonzero!(NonZeroU32, 1, u32::MAX); |
| 108 | +bounded_impl_nonzero!(NonZeroU64, 1, u64::MAX); |
| 109 | +bounded_impl_nonzero!(NonZeroU128, 1, u128::MAX); |
| 110 | + |
| 111 | +bounded_impl_nonzero!(NonZeroIsize, isize::MIN, isize::MAX); |
| 112 | +bounded_impl_nonzero!(NonZeroI8, i8::MIN, i8::MAX); |
| 113 | +bounded_impl_nonzero!(NonZeroI16, i16::MIN, i16::MAX); |
| 114 | +bounded_impl_nonzero!(NonZeroI32, i32::MIN, i32::MAX); |
| 115 | +bounded_impl_nonzero!(NonZeroI64, i64::MIN, i64::MAX); |
| 116 | +bounded_impl_nonzero!(NonZeroI128, i128::MIN, i128::MAX); |
| 117 | + |
71 | 118 | impl<T: Bounded> Bounded for Wrapping<T> {
|
72 | 119 | fn min_value() -> Self {
|
73 | 120 | Wrapping(T::min_value())
|
@@ -146,3 +193,37 @@ fn wrapping_is_bounded() {
|
146 | 193 | require_bounded(&Wrapping(42_u32));
|
147 | 194 | require_bounded(&Wrapping(-42));
|
148 | 195 | }
|
| 196 | + |
| 197 | +#[test] |
| 198 | +fn bounded_unsigned_nonzero() { |
| 199 | + macro_rules! test_bounded_impl_unsigned_nonzero { |
| 200 | + ($t:ty, $base_ty:ty) => { |
| 201 | + assert_eq!(<$t as Bounded>::min_value().get(), 1); |
| 202 | + assert_eq!(<$t as Bounded>::max_value().get(), <$base_ty>::MAX); |
| 203 | + }; |
| 204 | + } |
| 205 | + |
| 206 | + test_bounded_impl_unsigned_nonzero!(NonZeroUsize, usize); |
| 207 | + test_bounded_impl_unsigned_nonzero!(NonZeroU8, u8); |
| 208 | + test_bounded_impl_unsigned_nonzero!(NonZeroU16, u16); |
| 209 | + test_bounded_impl_unsigned_nonzero!(NonZeroU32, u32); |
| 210 | + test_bounded_impl_unsigned_nonzero!(NonZeroU64, u64); |
| 211 | + test_bounded_impl_unsigned_nonzero!(NonZeroU128, u128); |
| 212 | +} |
| 213 | + |
| 214 | +#[test] |
| 215 | +fn bounded_signed_nonzero() { |
| 216 | + macro_rules! test_bounded_impl_signed_nonzero { |
| 217 | + ($t:ty, $base_ty:ty) => { |
| 218 | + assert_eq!(<$t as Bounded>::min_value().get(), <$base_ty>::MIN); |
| 219 | + assert_eq!(<$t as Bounded>::max_value().get(), <$base_ty>::MAX); |
| 220 | + }; |
| 221 | + } |
| 222 | + |
| 223 | + test_bounded_impl_signed_nonzero!(NonZeroIsize, isize); |
| 224 | + test_bounded_impl_signed_nonzero!(NonZeroI8, i8); |
| 225 | + test_bounded_impl_signed_nonzero!(NonZeroI16, i16); |
| 226 | + test_bounded_impl_signed_nonzero!(NonZeroI32, i32); |
| 227 | + test_bounded_impl_signed_nonzero!(NonZeroI64, i64); |
| 228 | + test_bounded_impl_signed_nonzero!(NonZeroI128, i128); |
| 229 | +} |
0 commit comments