2025-07-29 12:38:11 -04:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Sealed with Magistamp.
|
|
|
|
|
2025-03-10 12:17:37 -04:00
|
|
|
/// Primitive types that have upper and lower bounds.
|
|
|
|
pub trait Bounded
|
|
|
|
{
|
|
|
|
/// The minimum value for this type.
|
|
|
|
const MIN: Self;
|
|
|
|
|
|
|
|
/// The maximum value for this type.
|
|
|
|
const MAX: Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A macro for making implementation of
|
|
|
|
/// the Bounded trait easier.
|
|
|
|
macro_rules! bounded_trait_impl
|
|
|
|
{
|
|
|
|
($T: ty, $minVal: expr, $maxVal: expr) =>
|
|
|
|
{
|
|
|
|
impl Bounded for $T
|
|
|
|
{
|
|
|
|
const MIN: $T = $minVal;
|
|
|
|
|
|
|
|
const MAX: $T = $maxVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Implement the Bounded for all the primitive types.
|
|
|
|
bounded_trait_impl!(u8, 0u8, !0u8);
|
|
|
|
bounded_trait_impl!(u16, 0u16, !0u16);
|
|
|
|
bounded_trait_impl!(u32, 0u32, !0u32);
|
|
|
|
bounded_trait_impl!(u64, 0u64, !0u64);
|
|
|
|
bounded_trait_impl!(usize, 0usize, !0usize);
|
|
|
|
|
|
|
|
bounded_trait_impl!(i8, (!0i8 ^ (!0u8 >> 1u8) as i8),
|
|
|
|
!(!0i8 ^ (!0u8 >> 1u8) as i8));
|
|
|
|
bounded_trait_impl!(i16, (!0i16 ^ (!0u16 >> 1u16) as i16),
|
|
|
|
!(!0i16 ^ (!0u16 >> 1u16) as i16));
|
|
|
|
bounded_trait_impl!(i32, (!0i32 ^ (!0u32 >> 1u32) as i32),
|
|
|
|
!(!0i32 ^ (!0u32 >> 1u32) as i32));
|
|
|
|
bounded_trait_impl!(i64, (!0i64 ^ (!0u64 >> 1u64) as i64),
|
|
|
|
!(!0i64 ^ (!0u64 >> 1u64) as i64));
|
|
|
|
bounded_trait_impl!(isize, (!0isize ^ (!0usize >> 1usize) as isize),
|
|
|
|
!(!0isize ^ (!0usize >> 1usize) as isize));
|
|
|
|
|
|
|
|
bounded_trait_impl!(f32, -3.40282347e+38f32, 3.40282347e+38f32);
|
|
|
|
bounded_trait_impl!(f64, -1.7976931348623157e+308f64,
|
|
|
|
1.7976931348623157e+308f64);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests
|
|
|
|
{
|
|
|
|
macro_rules! bounds_test
|
|
|
|
{
|
|
|
|
($T: ident, $func_name: ident, $minVal: expr, $maxVal: expr) =>
|
|
|
|
{
|
|
|
|
#[test]
|
|
|
|
fn $func_name()
|
|
|
|
{
|
|
|
|
assert_eq!($T::MIN, $minVal);
|
|
|
|
assert_eq!($T::MAX, $maxVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds_test!(u8, min_max_u8, 0u8, !0u8);
|
|
|
|
bounds_test!(u16, min_max_u16, 0u16, !0u16);
|
|
|
|
bounds_test!(u32, min_max_u32, 0u32, !0u32);
|
|
|
|
bounds_test!(u64, min_max_u64, 0u64, !0u64);
|
|
|
|
bounds_test!(usize, min_max_usize, 0usize, !0usize);
|
|
|
|
|
|
|
|
bounds_test!(i8, min_max_i8,
|
|
|
|
-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8),
|
|
|
|
!(-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8)));
|
|
|
|
bounds_test!(i16, min_max_i16,
|
|
|
|
-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16),
|
|
|
|
!(-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16)));
|
|
|
|
bounds_test!(i32, min_max_i32,
|
|
|
|
-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32),
|
|
|
|
!(-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32)));
|
|
|
|
bounds_test!(i64, min_max_i64,
|
|
|
|
-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64),
|
|
|
|
!(-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64)));
|
|
|
|
bounds_test!(isize, min_max_isize,
|
|
|
|
-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize),
|
|
|
|
!(-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize)));
|
|
|
|
|
|
|
|
bounds_test!(f32, min_max_f32,
|
|
|
|
-3.40282347e+38f32, 3.40282347e+38f32);
|
|
|
|
bounds_test!(f64, min_max_f64,
|
|
|
|
-1.7976931348623157e+308f64,
|
|
|
|
1.7976931348623157e+308f64);
|
|
|
|
}
|