relp_num/non_zero/
mod.rs

1//! # NonZero values
2//!
3//! Relp often works with sparse structures where many values are zero.
4use std::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
5use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
6
7pub use sign::NonZeroSign as NonZeroSign;
8pub use sign::NonZeroSigned as NonZeroSigned;
9
10pub mod sign;
11
12/// # Nonzero values
13///
14/// In contexts where this trait is required, implementors should not have value zero.
15///
16/// This trait is used for debug asserts. Values in sparse data structures should never be zero, and
17/// requiring that they implement `num_traits::Zero` prohibits writing number types that can't
18/// represent the value 0.
19///
20/// The `num_traits::Zero` trait is for types that can be zero, this trait is for types that can be
21/// a value other than zero. They may or may not be able to represent zero.
22pub trait NonZero {
23    /// Whether the value is not equal to zero.
24    ///
25    /// Should always be `true` in the context in which it is called.
26    fn is_not_zero(&self) -> bool;
27}
28
29macro_rules! could_be_zero {
30    ($t:ty) => {
31        impl NonZero for $t {
32            #[must_use]
33            #[inline]
34            fn is_not_zero(&self) -> bool {
35                !num_traits::Zero::is_zero(self)
36            }
37        }
38    }
39}
40
41could_be_zero!(i8);
42could_be_zero!(u8);
43could_be_zero!(i16);
44could_be_zero!(u16);
45could_be_zero!(i32);
46could_be_zero!(u32);
47could_be_zero!(i64);
48could_be_zero!(u64);
49could_be_zero!(i128);
50could_be_zero!(u128);
51could_be_zero!(isize);
52could_be_zero!(usize);
53could_be_zero!(f32);
54could_be_zero!(f64);
55
56/// Consider the tuple a ratio (hence the debug assert).
57macro_rules! could_be_zero_tuple {
58    ($t:ty) => {
59        impl NonZero for ($t, $t) {
60            #[must_use]
61            #[inline]
62            fn is_not_zero(&self) -> bool {
63                debug_assert!(self.1.is_not_zero());
64
65                self.0.is_not_zero()
66            }
67        }
68    }
69}
70
71could_be_zero_tuple!(i8);
72could_be_zero_tuple!(u8);
73could_be_zero_tuple!(i16);
74could_be_zero_tuple!(u16);
75could_be_zero_tuple!(i32);
76could_be_zero_tuple!(u32);
77could_be_zero_tuple!(i64);
78could_be_zero_tuple!(u64);
79could_be_zero_tuple!(i128);
80could_be_zero_tuple!(u128);
81could_be_zero_tuple!(isize);
82could_be_zero_tuple!(usize);
83could_be_zero_tuple!(f32);
84could_be_zero_tuple!(f64);
85
86macro_rules! can_not_be_zero {
87    ($t:ty) => {
88        impl NonZero for $t {
89            #[must_use]
90            #[inline]
91            fn is_not_zero(&self) -> bool {
92                true
93            }
94        }
95    }
96}
97
98can_not_be_zero!(NonZeroI8);
99can_not_be_zero!(NonZeroI16);
100can_not_be_zero!(NonZeroI32);
101can_not_be_zero!(NonZeroI64);
102can_not_be_zero!(NonZeroI128);
103can_not_be_zero!(NonZeroIsize);
104can_not_be_zero!(NonZeroU8);
105can_not_be_zero!(NonZeroU16);
106can_not_be_zero!(NonZeroU32);
107can_not_be_zero!(NonZeroU64);
108can_not_be_zero!(NonZeroU128);
109can_not_be_zero!(NonZeroUsize);