/// 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::() as i8)*8i8)-1i8), !(-1i8 << (((::std::mem::size_of::() as i8)*8i8)-1i8))); bounds_test!(i16, min_max_i16, -1i16 << (((::std::mem::size_of::() as i16)*8i16)-1i16), !(-1i16 << (((::std::mem::size_of::() as i16)*8i16)-1i16))); bounds_test!(i32, min_max_i32, -1i32 << (((::std::mem::size_of::() as i32)*8i32)-1i32), !(-1i32 << (((::std::mem::size_of::() as i32)*8i32)-1i32))); bounds_test!(i64, min_max_i64, -1i64 << (((::std::mem::size_of::() as i64)*8i64)-1i64), !(-1i64 << (((::std::mem::size_of::() as i64)*8i64)-1i64))); bounds_test!(isize, min_max_isize, -1isize << (((::std::mem::size_of::() as isize)*8isize)-1isize), !(-1isize << (((::std::mem::size_of::() 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); }