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 let zero = const_zero::<u8, 2, Nct>();
129 assert!(const_is_zero(&zero));
130 assert!(!const_is_one(&zero));
131
132 let one = const_one::<u8, 2, Nct>();
134 assert!(!const_is_zero(&one));
135 assert!(const_is_one(&one));
136
137 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 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}