fixed_bigint/fixeduint/
num_traits_identity.rs1use 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 let zero = const_zero::<u8, 2>();
133 assert!(const_is_zero(&zero));
134 assert!(!const_is_one(&zero));
135
136 let one = const_one::<u8, 2>();
138 assert!(!const_is_zero(&one));
139 assert!(const_is_one(&one));
140
141 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 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}