1use std::collections::BTreeMap;
12
13use const_num_traits::{
14 BitIndex, BitIndexOps, DivNonZero, Finite, HasNonZero, NonMin, NonNegative, Odd, Positive,
15 PowerOfTwo, PowerOfTwoOps,
16};
17
18fn power_of_two() {
21 let radix = 256u64;
22 let p = PowerOfTwo::<u64>::new(radix).expect("256 is 2^8");
23
24 assert_eq!(700u64.rem_pow2(p), 700 % 256); assert_eq!(700u64.div_pow2(p), 700 / 256); assert_eq!(700u64.next_multiple_of_pow2(p), 768);
30 assert_eq!(u64::MAX.checked_next_multiple_of_pow2(p), None);
31
32 let mut folded = 0u64;
34 for limb in [10u64, 600, 70_000] {
35 folded ^= limb.rem_pow2(p);
36 }
37 assert_eq!(folded, (10 ^ 600 ^ 70_000) & 0xFF);
38}
39
40fn bit_index() {
43 let pos = BitIndex::<u64>::new(40).expect("40 < 64");
44 assert_eq!((1u64).shl_index(pos), 1u64 << 40);
45 assert_eq!((1u64 << 63).shr_index(pos), (1u64 << 63) >> 40);
46
47 assert!(BitIndex::<u64>::new(64).is_none());
49}
50
51fn nonzero_division() {
54 let d = 17u32.into_nonzero().expect("17 != 0");
55 assert_eq!(100u32.div_nonzero(d), 100 / 17);
56 assert_eq!(100u32.rem_nonzero(d), 100 % 17);
57 assert!(0u32.into_nonzero().is_none());
58}
59
60fn signed_range() {
63 let nn = NonNegative::<i32>::new(81).expect("81 >= 0");
64 let u: u32 = nn.to_unsigned(); assert_eq!(u, 81);
66 assert_eq!(nn.isqrt(), 9); let nz = Positive::<i32>::new(7).expect("7 > 0").into_nonzero();
70 assert_eq!(nz.get(), 7);
71}
72
73fn nonmin() {
76 let a = NonMin::<i32>::new(-7).expect("-7 != MIN");
77 assert_eq!(a.abs(), 7); assert_eq!(a.neg(), 7);
79
80 let d = core::num::NonZero::new(2).unwrap();
82 assert_eq!(a.div_nonzero(d), -7 / 2);
83
84 let q = Positive::<i32>::new(9).unwrap().into_nonmin();
86 assert_eq!(q.abs(), 9);
87
88 assert!(NonMin::<i32>::new(i32::MIN).is_none());
89}
90
91fn odd_modulus() {
95 let m = Odd::<u64>::new(0xFFFF_FFFF_FFFF_FFC5).expect("a large odd prime");
97 assert_eq!(m.get() & 1, 1);
100
101 assert!(Odd::<u64>::new(0).is_none()); assert!(Odd::<u64>::new(10).is_none());
103}
104
105fn finite_floats() {
108 let raw = [2.0f64, f64::NAN, 1.0, f64::INFINITY, 0.5];
109
110 let mut xs: Vec<Finite<f64>> = raw.iter().copied().filter_map(Finite::<f64>::new).collect();
112 xs.sort(); let sorted: Vec<f64> = xs.iter().map(|f| f.get()).collect();
114 assert_eq!(sorted, [0.5, 1.0, 2.0]);
115
116 let mut table: BTreeMap<Finite<f64>, &str> = BTreeMap::new();
118 table.insert(Finite::<f64>::new(1.0).unwrap(), "one");
119 table.insert(Finite::<f64>::new(2.0).unwrap(), "two");
120 assert_eq!(table.get(&Finite::<f64>::new(1.0).unwrap()), Some(&"one"));
121}
122
123#[cfg(feature = "ct")]
127fn constant_time() {
128 use const_num_traits::CtNonZero; assert!(bool::from(Odd::<u64>::new_ct(0xABCD_1235).is_some()));
132 assert!(bool::from(Odd::<u64>::new_ct(0xABCD_1234).is_none()));
133 assert!(bool::from(42u32.into_nonzero_ct().is_some()));
134 assert!(bool::from(0u32.into_nonzero_ct().is_none()));
135}
136
137fn main() {
138 power_of_two();
139 bit_index();
140 nonzero_division();
141 signed_range();
142 nonmin();
143 odd_modulus();
144 finite_floats();
145 #[cfg(feature = "ct")]
146 constant_time();
147
148 println!("all typestate examples ran");
149}