radix_common/math/bnum_integer/bits.rs
1use super::*;
2
3macro_rules! impl_bits {
4 ($($t:ident, $wrapped:ty),*) => {
5 $(
6 paste! {
7 impl $t {
8 /// Returns the number of ones in the binary representation of `self`.
9 ///
10 #[inline]
11 #[doc(alias = "popcount")]
12 #[doc(alias = "popcnt")]
13 #[must_use = "this returns the result of the operation, \
14 without modifying the original"]
15 pub const fn count_ones(self) -> u32 {
16 self.0.count_ones()
17 }
18
19 /// Returns the number of zeros in the binary representation of `self`.
20 ///
21 #[inline]
22 #[must_use = "this returns the result of the operation, \
23 without modifying the original"]
24 pub const fn count_zeros(self) -> u32 {
25 self.0.count_zeros()
26 }
27
28 /// Returns the number of trailing zeros in the binary representation of `self`.
29 ///
30 #[inline]
31 #[must_use = "this returns the result of the operation, \
32 without modifying the original"]
33 pub const fn trailing_zeros(self) -> u32 {
34 self.0.trailing_zeros()
35 }
36
37 /// Reverses the byte order of the integer.
38 ///
39 #[inline]
40 #[must_use = "this returns the result of the operation, \
41 without modifying the original"]
42 pub const fn swap_bytes(self) -> Self {
43 Self(self.0.swap_bytes())
44 }
45
46 /// Reverses the bit pattern of the integer.
47 ///
48 #[must_use = "this returns the result of the operation, \
49 without modifying the original"]
50 #[inline]
51 pub const fn reverse_bits(self) -> Self {
52 Self(self.0.reverse_bits())
53 }
54
55 /// Returns the number of leading zeros in the binary representation of `self`.
56 ///
57 #[inline]
58 #[must_use = "this returns the result of the operation, \
59 without modifying the original"]
60 pub const fn leading_zeros(self) -> u32 {
61 self.0.leading_zeros()
62 }
63
64 /// Converts an integer from big endian to the target's endianness.
65 ///
66 /// On big endian this is a no-op. On little endian the bytes are
67 /// swapped.
68 ///
69 #[inline]
70 #[must_use]
71 pub const fn from_be(x: Self) -> Self {
72 if cfg!(target_endian = "big") {
73 x
74 } else {
75 Self(<$wrapped>::from_be(x.0))
76 }
77 }
78
79 /// Converts an integer from little endian to the target's endianness.
80 ///
81 /// On little endian this is a no-op. On big endian the bytes are
82 /// swapped.
83 ///
84 #[inline]
85 #[must_use]
86 pub const fn from_le(x: Self) -> Self {
87 if cfg!(target_endian = "big") {
88 Self(<$wrapped>::from_be(x.0))
89 } else {
90 x
91 }
92 }
93
94 /// Converts `self` to big endian from the target's endianness.
95 ///
96 /// On big endian this is a no-op. On little endian the bytes are
97 /// swapped.
98 ///
99 #[inline]
100 #[must_use = "this returns the result of the operation, \
101 without modifying the original"]
102 pub const fn to_be(self) -> Self {
103 if cfg!(target_endian = "big") {
104 self
105 } else {
106 Self(self.0.to_be())
107 }
108 }
109
110 /// Converts `self` to little endian from the target's endianness.
111 ///
112 /// On little endian this is a no-op. On big endian the bytes are
113 /// swapped.
114 ///
115 #[inline]
116 #[must_use = "this returns the result of the operation, \
117 without modifying the original"]
118 pub const fn to_le(self) -> Self {
119 if cfg!(target_endian = "big") {
120 Self(self.0.to_le())
121 } else {
122 self
123 }
124 }
125 }
126
127 impl BitXor for $t {
128 type Output = Self;
129
130 #[inline]
131 fn bitxor(self, other: Self) -> Self {
132 Self(self.0 ^ other.0)
133 }
134 }
135
136 impl BitXorAssign for $t {
137 #[inline]
138 fn bitxor_assign(&mut self, other: Self) {
139 self.0 ^= other.0
140 }
141 }
142
143 impl BitOr for $t {
144 type Output = Self;
145
146 #[inline]
147 fn bitor(self, other: Self) -> Self {
148 Self(self.0 | other.0)
149 }
150 }
151
152 impl BitOrAssign for $t {
153 #[inline]
154 fn bitor_assign(&mut self, other: Self) {
155 self.0 |= other.0
156 }
157 }
158
159 impl BitAnd for $t {
160 type Output = Self;
161
162 #[inline]
163 fn bitand(self, other: Self) -> Self {
164 Self(self.0 & other.0)
165 }
166 }
167
168 impl BitAndAssign for $t {
169 #[inline]
170 fn bitand_assign(&mut self, other: Self) {
171 self.0 &= other.0
172 }
173 }
174
175 impl Shl<u32> for $t {
176 type Output = Self;
177
178 #[inline]
179 fn shl(self, other: u32) -> Self {
180 Self(self.0.checked_shl(other).expect("Overflow"))
181 }
182 }
183
184
185 impl ShlAssign<u32> for $t {
186 #[inline]
187 fn shl_assign(&mut self, other: u32) {
188 self.0 = self.0.checked_shl(other).expect("Overflow");
189 }
190 }
191
192 impl Shr<u32> for $t {
193 type Output = Self;
194
195 #[inline]
196 fn shr(self, other: u32) -> $t {
197 Self(self.0.checked_shr(other).expect("Overflow"))
198 }
199 }
200
201 impl ShrAssign<u32> for $t {
202 #[inline]
203 fn shr_assign(&mut self, other: u32) {
204 self.0 = self.0.checked_shr(other).expect("Overflow");
205 }
206 }
207 }
208 )*
209 }
210}
211impl_bits! { I192, BInt::<3> }
212impl_bits! { I256, BInt::<4> }
213impl_bits! { I320, BInt::<5> }
214impl_bits! { I384, BInt::<6> }
215impl_bits! { I448, BInt::<7> }
216impl_bits! { I512, BInt::<8> }
217impl_bits! { I768, BInt::<12> }
218impl_bits! { U192, BUint::<3> }
219impl_bits! { U256, BUint::<4> }
220impl_bits! { U320, BUint::<5> }
221impl_bits! { U384, BUint::<6> }
222impl_bits! { U448, BUint::<7> }
223impl_bits! { U512, BUint::<8> }
224impl_bits! { U768, BUint::<12> }