Skip to main content

fixed_bigint/fixeduint/
num_traits_identity.rs

1use super::{const_is_zero, FixedUInt, MachineWord};
2use crate::const_numtraits::{ConstBounded, ConstOne, ConstZero};
3use crate::machineword::ConstMachineWord;
4
5c0nst::c0nst! {
6    impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstZero for FixedUInt<T, N> {
7        fn zero() -> Self {
8            FixedUInt {
9                array: [T::zero(); N],
10            }
11        }
12        fn is_zero(&self) -> bool {
13            const_is_zero(&self.array)
14        }
15        fn set_zero(&mut self) {
16            let mut i = 0;
17            while i < N {
18                self.array[i].set_zero();
19                i += 1;
20            }
21        }
22    }
23
24    impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstOne for FixedUInt<T, N> {
25        fn one() -> Self {
26            let mut ret = <Self as ConstZero>::zero();
27            if N > 0 {
28                ret.array[0] = T::one();
29            }
30            ret
31        }
32        fn is_one(&self) -> bool {
33            if N == 0 || !self.array[0].is_one() {
34                return false;
35            }
36            let mut i = 1;
37            while i < N {
38                if !self.array[i].is_zero() {
39                    return false;
40                }
41                i += 1;
42            }
43            true
44        }
45        fn set_one(&mut self) {
46            <Self as ConstZero>::set_zero(self);
47            if N > 0 {
48                self.array[0].set_one();
49            }
50        }
51    }
52
53    impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstBounded for FixedUInt<T, N> {
54        fn min_value() -> Self {
55            <Self as ConstZero>::zero()
56        }
57        fn max_value() -> Self {
58            FixedUInt {
59                array: [T::max_value(); N],
60            }
61        }
62    }
63}
64
65impl<T: MachineWord, const N: usize> num_traits::Zero for FixedUInt<T, N> {
66    fn zero() -> Self {
67        <Self as ConstZero>::zero()
68    }
69    fn is_zero(&self) -> bool {
70        <Self as ConstZero>::is_zero(self)
71    }
72}
73
74impl<T: MachineWord, const N: usize> num_traits::One for FixedUInt<T, N> {
75    fn one() -> Self {
76        <Self as ConstOne>::one()
77    }
78}
79
80impl<T: MachineWord, const N: usize> num_traits::Bounded for FixedUInt<T, N> {
81    fn min_value() -> Self {
82        <Self as ConstBounded>::min_value()
83    }
84    fn max_value() -> Self {
85        <Self as ConstBounded>::max_value()
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    c0nst::c0nst! {
94        c0nst fn const_zero<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>() -> FixedUInt<T, N> {
95            <FixedUInt<T, N> as ConstZero>::zero()
96        }
97
98        c0nst fn const_one<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>() -> FixedUInt<T, N> {
99            <FixedUInt<T, N> as ConstOne>::one()
100        }
101
102        c0nst fn const_is_zero<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(v: &FixedUInt<T, N>) -> bool {
103            <FixedUInt<T, N> as ConstZero>::is_zero(v)
104        }
105
106        c0nst fn const_is_one<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(v: &FixedUInt<T, N>) -> bool {
107            <FixedUInt<T, N> as ConstOne>::is_one(v)
108        }
109
110        c0nst fn const_min_value<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>() -> FixedUInt<T, N> {
111            <FixedUInt<T, N> as ConstBounded>::min_value()
112        }
113
114        c0nst fn const_max_value<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>() -> FixedUInt<T, N> {
115            <FixedUInt<T, N> as ConstBounded>::max_value()
116        }
117
118        c0nst fn const_set_zero<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(v: &mut FixedUInt<T, N>) {
119            <FixedUInt<T, N> as ConstZero>::set_zero(v)
120        }
121
122        c0nst fn const_set_one<T: [c0nst] ConstMachineWord + MachineWord, const N: usize>(v: &mut FixedUInt<T, N>) {
123            <FixedUInt<T, N> as ConstOne>::set_one(v)
124        }
125    }
126
127    #[test]
128    fn test_const_identity_traits() {
129        type TestInt = FixedUInt<u8, 2>;
130
131        // Test zero
132        let zero = const_zero::<u8, 2>();
133        assert!(const_is_zero(&zero));
134        assert!(!const_is_one(&zero));
135
136        // Test one
137        let one = const_one::<u8, 2>();
138        assert!(!const_is_zero(&one));
139        assert!(const_is_one(&one));
140
141        // Test min/max
142        let min = const_min_value::<u8, 2>();
143        let max = const_max_value::<u8, 2>();
144        assert!(const_is_zero(&min));
145        assert_eq!(max.array, [255, 255]);
146
147        // Test set_zero/set_one
148        let mut val = TestInt::from(42u8);
149        const_set_zero(&mut val);
150        assert!(const_is_zero(&val));
151
152        const_set_one(&mut val);
153        assert!(const_is_one(&val));
154
155        #[cfg(feature = "nightly")]
156        {
157            const ZERO: TestInt = const_zero::<u8, 2>();
158            const ONE: TestInt = const_one::<u8, 2>();
159            const IS_ZERO_TRUE: bool = const_is_zero(&ZERO);
160            const IS_ZERO_FALSE: bool = const_is_zero(&ONE);
161            const IS_ONE_TRUE: bool = const_is_one(&ONE);
162            const IS_ONE_FALSE: bool = const_is_one(&ZERO);
163            const MIN: TestInt = const_min_value::<u8, 2>();
164            const MAX: TestInt = const_max_value::<u8, 2>();
165
166            assert_eq!(ZERO.array, [0, 0]);
167            assert_eq!(ONE.array, [1, 0]);
168            assert!(IS_ZERO_TRUE);
169            assert!(!IS_ZERO_FALSE);
170            assert!(IS_ONE_TRUE);
171            assert!(!IS_ONE_FALSE);
172            assert_eq!(MIN.array, [0, 0]);
173            assert_eq!(MAX.array, [255, 255]);
174
175            const SET_ZERO_RES: TestInt = {
176                let mut v = FixedUInt { array: [42, 0] };
177                const_set_zero(&mut v);
178                v
179            };
180            const SET_ONE_RES: TestInt = {
181                let mut v = FixedUInt { array: [0, 0] };
182                const_set_one(&mut v);
183                v
184            };
185            assert_eq!(SET_ZERO_RES.array, [0, 0]);
186            assert_eq!(SET_ONE_RES.array, [1, 0]);
187        }
188    }
189}