fixed_bigint/fixeduint/
prim_int_impl.rs1use super::{
2 const_leading_zeros, const_leading_zeros_ct, const_trailing_zeros, const_trailing_zeros_ct,
3 FixedUInt, MachineWord,
4};
5use crate::const_numtraits::{ConstBitPrimInt, ConstPrimInt};
6use crate::machineword::ConstMachineWord;
7
8use crate::personality::{Nct, Personality, PersonalityTag};
9use num_traits::One;
10
11c0nst::c0nst! {
12 impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize, P: Personality> c0nst ConstBitPrimInt for FixedUInt<T, N, P> {
13 fn count_ones(self) -> u32 {
14 let mut count = 0u32;
15 let mut i = 0;
16 while i < N {
17 count += self.array[i].count_ones();
18 i += 1;
19 }
20 count
21 }
22 fn count_zeros(self) -> u32 {
23 let mut count = 0u32;
24 let mut i = 0;
25 while i < N {
26 count += self.array[i].count_zeros();
27 i += 1;
28 }
29 count
30 }
31 fn leading_zeros(self) -> u32 {
32 match P::TAG {
33 PersonalityTag::Nct => const_leading_zeros(&self.array),
34 PersonalityTag::Ct => const_leading_zeros_ct(&self.array),
35 }
36 }
37 fn trailing_zeros(self) -> u32 {
38 match P::TAG {
39 PersonalityTag::Nct => const_trailing_zeros(&self.array),
40 PersonalityTag::Ct => const_trailing_zeros_ct(&self.array),
41 }
42 }
43 fn swap_bytes(self) -> Self {
44 let mut ret = <Self as crate::const_numtraits::ConstZero>::zero();
45 let mut i = 0;
46 while i < N {
47 ret.array[i] = self.array[N - 1 - i].swap_bytes();
48 i += 1;
49 }
50 ret
51 }
52 fn rotate_left(self, n: u32) -> Self {
53 let bit_size = Self::BIT_SIZE as u32;
54 if bit_size == 0 {
55 return self;
56 }
57 let shift = n % bit_size;
58 let a = core::ops::Shl::<u32>::shl(self, shift);
59 let b = core::ops::Shr::<u32>::shr(self, bit_size - shift);
60 core::ops::BitOr::bitor(a, b)
61 }
62 fn rotate_right(self, n: u32) -> Self {
63 let bit_size = Self::BIT_SIZE as u32;
64 if bit_size == 0 {
65 return self;
66 }
67 let shift = n % bit_size;
68 let a = core::ops::Shr::<u32>::shr(self, shift);
69 let b = core::ops::Shl::<u32>::shl(self, bit_size - shift);
70 core::ops::BitOr::bitor(a, b)
71 }
72 fn unsigned_shl(self, n: u32) -> Self {
73 core::ops::Shl::<u32>::shl(self, n)
74 }
75 fn unsigned_shr(self, n: u32) -> Self {
76 core::ops::Shr::<u32>::shr(self, n)
77 }
78 fn reverse_bits(self) -> Self {
79 let mut ret = <Self as crate::const_numtraits::ConstZero>::zero();
80 let mut i = 0;
81 while i < N {
82 ret.array[N - 1 - i] = self.array[i].reverse_bits();
83 i += 1;
84 }
85 ret
86 }
87 fn from_be(x: Self) -> Self {
89 x.swap_bytes()
90 }
91 fn from_le(x: Self) -> Self {
92 x
93 }
94 fn to_be(self) -> Self {
95 self.swap_bytes()
96 }
97 fn to_le(self) -> Self {
98 self
99 }
100 }
101 impl<T: [c0nst] ConstMachineWord + MachineWord, const N: usize> c0nst ConstPrimInt for FixedUInt<T, N, Nct> {
102 fn pow(self, exp: u32) -> Self {
103 if exp == 0 {
104 return <Self as crate::const_numtraits::ConstOne>::one();
105 }
106 let mut result = <Self as crate::const_numtraits::ConstOne>::one();
108 let mut base = self;
109 let mut e = exp;
110 while e > 0 {
111 if (e & 1) == 1 {
112 result = core::ops::Mul::mul(result, base);
113 }
114 e >>= 1;
115 if e > 0 {
116 base = core::ops::Mul::mul(base, base);
117 }
118 }
119 result
120 }
121 }
122}
123
124impl<T: MachineWord, const N: usize> num_traits::PrimInt for FixedUInt<T, N, Nct> {
125 fn count_ones(self) -> u32 {
126 self.array.iter().map(|&val| val.count_ones()).sum()
127 }
128 fn count_zeros(self) -> u32 {
129 self.array.iter().map(|&val| val.count_zeros()).sum()
130 }
131 fn leading_zeros(self) -> u32 {
132 const_leading_zeros(&self.array)
133 }
134 fn trailing_zeros(self) -> u32 {
135 const_trailing_zeros(&self.array)
136 }
137 fn rotate_left(self, bits: u32) -> Self {
138 let bit_size = Self::BIT_SIZE as u32;
139 if bit_size == 0 {
140 return self;
141 }
142 let shift = bits % bit_size;
143 let a = self << shift;
144 let b = self >> (bit_size - shift);
145 a | b
146 }
147 fn rotate_right(self, bits: u32) -> Self {
148 let bit_size = Self::BIT_SIZE as u32;
149 if bit_size == 0 {
150 return self;
151 }
152 let shift = bits % bit_size;
153 let a = self >> shift;
154 let b = self << (bit_size - shift);
155 a | b
156 }
157 fn signed_shl(self, bits: u32) -> Self {
158 <Self as num_traits::PrimInt>::unsigned_shl(self, bits)
159 }
160 fn signed_shr(self, bits: u32) -> Self {
161 <Self as num_traits::PrimInt>::unsigned_shr(self, bits)
162 }
163 fn unsigned_shl(self, bits: u32) -> Self {
164 self << bits
165 }
166 fn unsigned_shr(self, bits: u32) -> Self {
167 self >> bits
168 }
169 fn swap_bytes(self) -> Self {
170 let mut ret = Self::new();
171 for index in 0..N {
172 ret.array[index] = self.array[N - 1 - index].swap_bytes();
173 }
174
175 ret
176 }
177 fn from_be(source: Self) -> Self {
179 <Self as num_traits::PrimInt>::swap_bytes(source)
180 }
181 fn from_le(source: Self) -> Self {
182 source
183 }
184 fn to_be(self) -> Self {
185 <Self as num_traits::PrimInt>::swap_bytes(self)
186 }
187 fn to_le(self) -> Self {
188 self
189 }
190 fn pow(self, exp: u32) -> Self {
191 if exp == 0 {
192 return Self::one();
193 }
194 let mut result = Self::one();
196 let mut base = self;
197 let mut e = exp;
198 while e > 0 {
199 if (e & 1) == 1 {
200 result *= base;
201 }
202 e >>= 1;
203 if e > 0 {
204 base *= base;
205 }
206 }
207 result
208 }
209}