Skip to main content

relp_num/non_zero/
mod.rs

1//! # NonZero values
2//!
3//! Relp often works with sparse structures where many values are zero.
4pub use sign::NonZeroSign as NonZeroSign;
5pub use sign::NonZeroSigned as NonZeroSigned;
6
7pub mod sign;
8
9/// # Nonzero values
10///
11/// In contexts where this trait is required, implementors should not have value zero.
12///
13/// This trait is used for debug asserts. Values in sparse data structures should never be zero, and
14/// requiring that they implement `num_traits::Zero` prohibits writing number types that can't
15/// represent the value 0.
16///
17/// The `num_traits::Zero` trait is for types that can be zero, this trait is for types that can be
18/// a value other than zero. They may or may not be able to represent zero.
19pub trait NonZero {
20    /// Whether the value is not equal to zero.
21    ///
22    /// Should always be `true` in the context in which it is called.
23    fn is_not_zero(&self) -> bool;
24}
25
26macro_rules! could_be_zero {
27    ($($t:ty),+ $(,)?) => {$(
28        impl NonZero for $t {
29            #[inline]
30            fn is_not_zero(&self) -> bool {
31                !num_traits::Zero::is_zero(self)
32            }
33        }
34    )+}
35}
36
37could_be_zero!(i8, i16, i32, i64, i128, isize);
38could_be_zero!(u8, u16, u32, u64, u128, usize);
39could_be_zero!(f32, f64);
40
41/// The `std` counterparts, which state the same thing in their type.
42///
43/// Spelled `std::num::NonZero<..>` rather than imported, because the name would otherwise clash
44/// with the trait being implemented.
45macro_rules! can_not_be_zero {
46    ($($t:ty),+ $(,)?) => {$(
47        impl NonZero for std::num::NonZero<$t> {
48            #[inline]
49            fn is_not_zero(&self) -> bool {
50                true
51            }
52        }
53    )+}
54}
55
56can_not_be_zero!(i8, i16, i32, i64, i128, isize);
57can_not_be_zero!(u8, u16, u32, u64, u128, usize);