Skip to main content

fixed_bigint/fixeduint/
num_traits_identity.rs

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