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> }