[#2] Cleaned up the base traits.

I have switched to using the `core::` calling convention instead of using
the `std::` by means of `extern crate core as std`. This makes it so
that the library is easier to reason.

The `Number` trait has been broken up now into `Number` and `Natural`.
This was done to make it so that the pure mathematical types were
separate from the Rust implementation types.

I went and added better comments, including examples.

The macros were tightened up so that the implementations took up less
space.

The FromNumber and ToNumber stuff will need to be reimplemented yet.
Some of it seemed redundant with From and TryFrom traits now. It will be
something to come back to and implement at the end.
This commit is contained in:
2026-02-12 19:21:53 -05:00
parent b014dd959c
commit fbef05fcd1
6 changed files with 238 additions and 1053 deletions

View File

@ -1,13 +1,38 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
/// Primitive types that have upper and lower bounds.
/// `Bounded` provides the inclusive minimum and maximum range limits
/// for a numeric type.
///
/// Rust types have actual upper and lower representation limits that don't
/// follow the mathematical definitions. For example a Natural number goes
/// from one to infinity but a u8 can only really represent a number between
/// zero and two hundred and fifty five. This let's use set the minimum and
/// maximum values a Rust type can represent so we can use them in code easily.
pub trait Bounded
{
/// The minimum value for this type.
///
/// # Examples
/// ```rust
/// use sigils::Bounded;
///
/// let min = <u8 as Bounded>::MIN;
///
/// assert_eq!(min, u8::MIN);
/// ```
const MIN: Self;
/// The maximum value for this type.
///
/// # Examples
/// ```rust
/// use sigils::Bounded;
///
/// let max = <f64 as Bounded>::MAX;
///
/// assert_eq!(max, f64::MAX);
/// ```
const MAX: Self;
}
@ -17,83 +42,20 @@ pub trait Bounded
/// the Bounded trait easier.
macro_rules! bounded_trait_impl
{
($T: ty, $minVal: expr, $maxVal: expr) =>
($($T:ty),*) =>
{
impl Bounded for $T
{
const MIN: $T = $minVal;
const MAX: $T = $maxVal;
}
$(
impl Bounded for $T
{
const MIN: $T = <$T>::MIN;
const MAX: $T = <$T>::MAX;
}
)*
}
}
// 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);
}
bounded_trait_impl!(u8, u16, u32, u64, u128, usize);
bounded_trait_impl!(i8, i16, i32, i64, i128, isize);
bounded_trait_impl!(f32, f64);