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