num_primitive/
integer.rs

1use core::num::ParseIntError;
2
3use crate::{PrimitiveError, PrimitiveNumber, PrimitiveNumberRef};
4
5/// Trait for all primitive [integer types], including the supertrait [`PrimitiveNumber`].
6///
7/// This encapsulates trait implementations, constants, and inherent methods that are common among
8/// all of the primitive integer types: [`i8`], [`i16`], [`i32`], [`i64`], [`i128`], [`isize`],
9/// [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], and [`usize`].
10///
11/// See the corresponding items on the individual types for more documentation and examples.
12///
13/// This trait is sealed with a private trait to prevent downstream implementations, so we may
14/// continue to expand along with the standard library without worrying about breaking changes for
15/// implementors.
16///
17/// [integer types]: https://doc.rust-lang.org/reference/types/numeric.html#r-type.numeric.int
18///
19/// # Examples
20///
21/// ```
22/// use num_primitive::PrimitiveInteger;
23///
24/// fn div_rem<T: PrimitiveInteger>(a: T, b: T) -> (T, T) {
25///     (a / b, a % b)
26/// }
27///
28/// fn div_rem_euclid<T: PrimitiveInteger>(a: T, b: T) -> (T, T) {
29///     (a.div_euclid(b), a.rem_euclid(b))
30/// }
31///
32/// assert_eq!(div_rem::<u8>(48, 18), (2, 12));
33/// assert_eq!(div_rem::<i8>(-48, 18), (-2, -12));
34///
35/// assert_eq!(div_rem_euclid::<u8>(48, 18), (2, 12));
36/// assert_eq!(div_rem_euclid::<i8>(-48, 18), (-3, 6));
37/// ```
38///
39pub trait PrimitiveInteger:
40    PrimitiveNumber
41    + core::cmp::Eq
42    + core::cmp::Ord
43    + core::convert::TryFrom<i8, Error: PrimitiveError>
44    + core::convert::TryFrom<i16, Error: PrimitiveError>
45    + core::convert::TryFrom<i32, Error: PrimitiveError>
46    + core::convert::TryFrom<i64, Error: PrimitiveError>
47    + core::convert::TryFrom<i128, Error: PrimitiveError>
48    + core::convert::TryFrom<isize, Error: PrimitiveError>
49    + core::convert::TryFrom<u8, Error: PrimitiveError>
50    + core::convert::TryFrom<u16, Error: PrimitiveError>
51    + core::convert::TryFrom<u32, Error: PrimitiveError>
52    + core::convert::TryFrom<u64, Error: PrimitiveError>
53    + core::convert::TryFrom<u128, Error: PrimitiveError>
54    + core::convert::TryFrom<usize, Error: PrimitiveError>
55    + core::convert::TryInto<i8, Error: PrimitiveError>
56    + core::convert::TryInto<i16, Error: PrimitiveError>
57    + core::convert::TryInto<i32, Error: PrimitiveError>
58    + core::convert::TryInto<i64, Error: PrimitiveError>
59    + core::convert::TryInto<i128, Error: PrimitiveError>
60    + core::convert::TryInto<isize, Error: PrimitiveError>
61    + core::convert::TryInto<u8, Error: PrimitiveError>
62    + core::convert::TryInto<u16, Error: PrimitiveError>
63    + core::convert::TryInto<u32, Error: PrimitiveError>
64    + core::convert::TryInto<u64, Error: PrimitiveError>
65    + core::convert::TryInto<u128, Error: PrimitiveError>
66    + core::convert::TryInto<usize, Error: PrimitiveError>
67    + core::fmt::Binary
68    + core::fmt::LowerHex
69    + core::fmt::Octal
70    + core::fmt::UpperHex
71    + core::hash::Hash
72    + core::ops::BitAnd<Self, Output = Self>
73    + core::ops::BitAndAssign<Self>
74    + core::ops::BitOr<Self, Output = Self>
75    + core::ops::BitOrAssign<Self>
76    + core::ops::BitXor<Self, Output = Self>
77    + core::ops::BitXorAssign<Self>
78    + core::ops::Not<Output = Self>
79    + core::ops::Shl<Self, Output = Self>
80    + core::ops::Shl<i8, Output = Self>
81    + core::ops::Shl<i16, Output = Self>
82    + core::ops::Shl<i32, Output = Self>
83    + core::ops::Shl<i64, Output = Self>
84    + core::ops::Shl<i128, Output = Self>
85    + core::ops::Shl<isize, Output = Self>
86    + core::ops::Shl<u8, Output = Self>
87    + core::ops::Shl<u16, Output = Self>
88    + core::ops::Shl<u32, Output = Self>
89    + core::ops::Shl<u64, Output = Self>
90    + core::ops::Shl<u128, Output = Self>
91    + core::ops::Shl<usize, Output = Self>
92    + core::ops::ShlAssign<Self>
93    + core::ops::ShlAssign<i8>
94    + core::ops::ShlAssign<i16>
95    + core::ops::ShlAssign<i32>
96    + core::ops::ShlAssign<i64>
97    + core::ops::ShlAssign<i128>
98    + core::ops::ShlAssign<isize>
99    + core::ops::ShlAssign<u8>
100    + core::ops::ShlAssign<u16>
101    + core::ops::ShlAssign<u32>
102    + core::ops::ShlAssign<u64>
103    + core::ops::ShlAssign<u128>
104    + core::ops::ShlAssign<usize>
105    + core::ops::Shr<Self, Output = Self>
106    + core::ops::Shr<i8, Output = Self>
107    + core::ops::Shr<i16, Output = Self>
108    + core::ops::Shr<i32, Output = Self>
109    + core::ops::Shr<i64, Output = Self>
110    + core::ops::Shr<i128, Output = Self>
111    + core::ops::Shr<isize, Output = Self>
112    + core::ops::Shr<u8, Output = Self>
113    + core::ops::Shr<u16, Output = Self>
114    + core::ops::Shr<u32, Output = Self>
115    + core::ops::Shr<u64, Output = Self>
116    + core::ops::Shr<u128, Output = Self>
117    + core::ops::Shr<usize, Output = Self>
118    + core::ops::ShrAssign<Self>
119    + core::ops::ShrAssign<i8>
120    + core::ops::ShrAssign<i16>
121    + core::ops::ShrAssign<i32>
122    + core::ops::ShrAssign<i64>
123    + core::ops::ShrAssign<i128>
124    + core::ops::ShrAssign<isize>
125    + core::ops::ShrAssign<u8>
126    + core::ops::ShrAssign<u16>
127    + core::ops::ShrAssign<u32>
128    + core::ops::ShrAssign<u64>
129    + core::ops::ShrAssign<u128>
130    + core::ops::ShrAssign<usize>
131    + core::str::FromStr<Err = ParseIntError>
132    + for<'a> core::ops::BitAnd<&'a Self, Output = Self>
133    + for<'a> core::ops::BitAndAssign<&'a Self>
134    + for<'a> core::ops::BitOr<&'a Self, Output = Self>
135    + for<'a> core::ops::BitOrAssign<&'a Self>
136    + for<'a> core::ops::BitXor<&'a Self, Output = Self>
137    + for<'a> core::ops::BitXorAssign<&'a Self>
138    + for<'a> core::ops::Shl<&'a Self, Output = Self>
139    + for<'a> core::ops::Shl<&'a i8, Output = Self>
140    + for<'a> core::ops::Shl<&'a i16, Output = Self>
141    + for<'a> core::ops::Shl<&'a i32, Output = Self>
142    + for<'a> core::ops::Shl<&'a i64, Output = Self>
143    + for<'a> core::ops::Shl<&'a i128, Output = Self>
144    + for<'a> core::ops::Shl<&'a isize, Output = Self>
145    + for<'a> core::ops::Shl<&'a u8, Output = Self>
146    + for<'a> core::ops::Shl<&'a u16, Output = Self>
147    + for<'a> core::ops::Shl<&'a u32, Output = Self>
148    + for<'a> core::ops::Shl<&'a u64, Output = Self>
149    + for<'a> core::ops::Shl<&'a u128, Output = Self>
150    + for<'a> core::ops::Shl<&'a usize, Output = Self>
151    + for<'a> core::ops::ShlAssign<&'a Self>
152    + for<'a> core::ops::ShlAssign<&'a i8>
153    + for<'a> core::ops::ShlAssign<&'a i16>
154    + for<'a> core::ops::ShlAssign<&'a i32>
155    + for<'a> core::ops::ShlAssign<&'a i64>
156    + for<'a> core::ops::ShlAssign<&'a i128>
157    + for<'a> core::ops::ShlAssign<&'a isize>
158    + for<'a> core::ops::ShlAssign<&'a u8>
159    + for<'a> core::ops::ShlAssign<&'a u16>
160    + for<'a> core::ops::ShlAssign<&'a u32>
161    + for<'a> core::ops::ShlAssign<&'a u64>
162    + for<'a> core::ops::ShlAssign<&'a u128>
163    + for<'a> core::ops::ShlAssign<&'a usize>
164    + for<'a> core::ops::Shr<&'a Self, Output = Self>
165    + for<'a> core::ops::Shr<&'a i8, Output = Self>
166    + for<'a> core::ops::Shr<&'a i16, Output = Self>
167    + for<'a> core::ops::Shr<&'a i32, Output = Self>
168    + for<'a> core::ops::Shr<&'a i64, Output = Self>
169    + for<'a> core::ops::Shr<&'a i128, Output = Self>
170    + for<'a> core::ops::Shr<&'a isize, Output = Self>
171    + for<'a> core::ops::Shr<&'a u8, Output = Self>
172    + for<'a> core::ops::Shr<&'a u16, Output = Self>
173    + for<'a> core::ops::Shr<&'a u32, Output = Self>
174    + for<'a> core::ops::Shr<&'a u64, Output = Self>
175    + for<'a> core::ops::Shr<&'a u128, Output = Self>
176    + for<'a> core::ops::Shr<&'a usize, Output = Self>
177    + for<'a> core::ops::ShrAssign<&'a Self>
178    + for<'a> core::ops::ShrAssign<&'a i8>
179    + for<'a> core::ops::ShrAssign<&'a i16>
180    + for<'a> core::ops::ShrAssign<&'a i32>
181    + for<'a> core::ops::ShrAssign<&'a i64>
182    + for<'a> core::ops::ShrAssign<&'a i128>
183    + for<'a> core::ops::ShrAssign<&'a isize>
184    + for<'a> core::ops::ShrAssign<&'a u8>
185    + for<'a> core::ops::ShrAssign<&'a u16>
186    + for<'a> core::ops::ShrAssign<&'a u32>
187    + for<'a> core::ops::ShrAssign<&'a u64>
188    + for<'a> core::ops::ShrAssign<&'a u128>
189    + for<'a> core::ops::ShrAssign<&'a usize>
190{
191    /// The size of this integer type in bits.
192    const BITS: u32;
193
194    /// The largest value that can be represented by this integer type.
195    const MAX: Self;
196
197    /// The smallest value that can be represented by this integer type.
198    const MIN: Self;
199
200    /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
201    fn checked_add(self, rhs: Self) -> Option<Self>;
202
203    /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0` or the
204    /// division results in overflow.
205    fn checked_div(self, rhs: Self) -> Option<Self>;
206
207    /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None` if `rhs == 0`
208    /// or the division results in overflow.
209    fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
210
211    /// Returns the logarithm of the number with respect to an arbitrary base, rounded down.
212    /// Returns `None` if the number is negative or zero, or if the base is not at least 2.
213    fn checked_ilog(self, base: Self) -> Option<u32>;
214
215    /// Returns the base 10 logarithm of the number, rounded down. Returns `None` if the number is
216    /// negative or zero.
217    fn checked_ilog10(self) -> Option<u32>;
218
219    /// Returns the base 2 logarithm of the number, rounded down. Returns `None` if the number is
220    /// negative or zero.
221    fn checked_ilog2(self) -> Option<u32>;
222
223    /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow
224    /// occurred.
225    fn checked_mul(self, rhs: Self) -> Option<Self>;
226
227    /// Checked negation. Computes -self, returning `None` if `self == MIN` for signed integers,
228    /// or for any non-zero unsigned integer.
229    fn checked_neg(self) -> Option<Self>;
230
231    /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if overflow occurred.
232    fn checked_pow(self, exp: u32) -> Option<Self>;
233
234    /// Checked integer remainder. Computes `self % rhs`, returning `None` if `rhs == 0` or the
235    /// division results in overflow.
236    fn checked_rem(self, rhs: Self) -> Option<Self>;
237
238    /// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None` if `rhs ==
239    /// 0` or the division results in overflow.
240    fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
241
242    /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger than or
243    /// equal to the number of bits in `self`.
244    fn checked_shl(self, rhs: u32) -> Option<Self>;
245
246    /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is larger than or
247    /// equal to the number of bits in `self`.
248    fn checked_shr(self, rhs: u32) -> Option<Self>;
249
250    /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
251    fn checked_sub(self, rhs: Self) -> Option<Self>;
252
253    /// Returns the number of ones in the binary representation of `self`.
254    fn count_ones(self) -> u32;
255
256    /// Returns the number of zeros in the binary representation of `self`.
257    fn count_zeros(self) -> u32;
258
259    /// Calculates the quotient of Euclidean division of `self` by `rhs`. This computes the integer
260    /// `q` such that `self = q * rhs + r`, with `r = self.rem_euclid(rhs)` and `0 <= r <
261    /// abs(rhs)`.
262    fn div_euclid(self, rhs: Self) -> Self;
263
264    /// Converts an integer from big endian to the target's endianness.
265    fn from_be(value: Self) -> Self;
266
267    /// Converts an integer from little endian to the target's endianness.
268    fn from_le(value: Self) -> Self;
269
270    /// Parses an integer from a string slice with digits in a given base.
271    fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
272
273    /// Returns the logarithm of the number with respect to an arbitrary base, rounded down.
274    fn ilog(self, base: Self) -> u32;
275
276    /// Returns the base 10 logarithm of the number, rounded down.
277    fn ilog10(self) -> u32;
278
279    /// Returns the base 2 logarithm of the number, rounded down.
280    fn ilog2(self) -> u32;
281
282    /// Returns the square root of the number, rounded down.
283    fn isqrt(self) -> Self;
284
285    /// Returns the number of leading ones in the binary representation of `self`.
286    fn leading_ones(self) -> u32;
287
288    /// Returns the number of leading zeros in the binary representation of `self`.
289    fn leading_zeros(self) -> u32;
290
291    /// Calculates `self + rhs`. Returns a tuple of the addition along with a boolean indicating
292    /// whether an arithmetic overflow would occur.
293    fn overflowing_add(self, rhs: Self) -> (Self, bool);
294
295    /// Calculates the divisor when `self` is divided by `rhs`. Returns a tuple of the divisor
296    /// along with a boolean indicating whether an arithmetic overflow would occur.
297    fn overflowing_div(self, rhs: Self) -> (Self, bool);
298
299    /// Calculates the quotient of Euclidean division `self`.div_euclid(rhs). Returns a tuple of
300    /// the divisor along with a boolean indicating whether an arithmetic overflow would occur.
301    fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
302
303    /// Calculates the multiplication of `self` and `rhs`. Returns a tuple of the multiplication
304    /// along with a boolean indicating whether an arithmetic overflow would occur.
305    fn overflowing_mul(self, rhs: Self) -> (Self, bool);
306
307    /// Negates self, overflowing if this is equal to the minimum value. Returns a tuple of the
308    /// negated version of `self` along with a boolean indicating whether an overflow happened.
309    fn overflowing_neg(self) -> (Self, bool);
310
311    /// Raises `self` to the power of `exp`, using exponentiation by squaring. Returns a tuple of
312    /// the exponentiation along with a bool indicating whether an overflow happened.
313    fn overflowing_pow(self, exp: u32) -> (Self, bool);
314
315    /// Calculates the remainder when `self` is divided by `rhs`. Returns a tuple of the remainder
316    /// after dividing along with a boolean indicating whether an arithmetic overflow would occur.
317    fn overflowing_rem(self, rhs: Self) -> (Self, bool);
318
319    /// Overflowing Euclidean remainder. Calculates `self`.rem_euclid(rhs). Returns a tuple of the
320    /// remainder after dividing along with a boolean indicating whether an arithmetic overflow
321    /// would occur.
322    fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool);
323
324    /// Shifts `self` left by `rhs` bits. Returns a tuple of the shifted version of `self` along
325    /// with a boolean indicating whether the shift value was larger than or equal to the number of
326    /// bits.
327    fn overflowing_shl(self, rhs: u32) -> (Self, bool);
328
329    /// Shifts `self` right by `rhs` bits. Returns a tuple of the shifted version of `self` along
330    /// with a boolean indicating whether the shift value was larger than or equal to the number of
331    /// bits.
332    fn overflowing_shr(self, rhs: u32) -> (Self, bool);
333
334    /// Calculates `self - rhs`. Returns a tuple of the subtraction along with a boolean indicating
335    /// whether an arithmetic overflow would occur.
336    fn overflowing_sub(self, rhs: Self) -> (Self, bool);
337
338    /// Raises `self` to the power of `exp`, using exponentiation by squaring.
339    fn pow(self, exp: u32) -> Self;
340
341    /// Calculates the least nonnegative remainder of `self (mod rhs)`. This is done as if by the
342    /// Euclidean division algorithm – given `r = self.rem_euclid(rhs)`, the result satisfies `self
343    /// = rhs * self.div_euclid(rhs) + r` and `0 <= r < abs(rhs)`.
344    fn rem_euclid(self, rhs: Self) -> Self;
345
346    /// Reverses the order of bits in the integer.
347    fn reverse_bits(self) -> Self;
348
349    /// Shifts the bits to the left by a specified amount, n, wrapping the truncated bits to the
350    /// end of the resulting integer.
351    fn rotate_left(self, n: u32) -> Self;
352
353    /// Shifts the bits to the right by a specified amount, n, wrapping the truncated bits to the
354    /// beginning of the resulting integer.
355    fn rotate_right(self, n: u32) -> Self;
356
357    /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric bounds
358    /// instead of overflowing.
359    fn saturating_add(self, rhs: Self) -> Self;
360
361    /// Saturating integer division. Computes `self / rhs`, saturating at the numeric bounds
362    /// instead of overflowing.
363    fn saturating_div(self, rhs: Self) -> Self;
364
365    /// Saturating integer multiplication. Computes `self * rhs`, saturating at the numeric bounds
366    /// instead of overflowing.
367    fn saturating_mul(self, rhs: Self) -> Self;
368
369    /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating at the numeric
370    /// bounds instead of overflowing.
371    fn saturating_pow(self, exp: u32) -> Self;
372
373    /// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric bounds
374    /// instead of overflowing.
375    fn saturating_sub(self, rhs: Self) -> Self;
376
377    /// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
378    fn strict_add(self, rhs: Self) -> Self;
379
380    /// Strict integer division. Computes `self / rhs`, panicking if overflow occurred.
381    fn strict_div(self, rhs: Self) -> Self;
382
383    /// Strict Euclidean division. Computes `self.div_euclid(rhs)`, panicking if overflow occurred.
384    fn strict_div_euclid(self, rhs: Self) -> Self;
385
386    /// Strict integer multiplication. Computes `self * rhs`, panicking if overflow occurred.
387    fn strict_mul(self, rhs: Self) -> Self;
388
389    /// Strict negation. Computes `-self`, panicking if `self == MIN` for signed integers,
390    /// or for any non-zero unsigned integer.
391    fn strict_neg(self) -> Self;
392
393    /// Strict exponentiation. Computes `self.pow(exp)`, panicking if overflow occurred.
394    fn strict_pow(self, exp: u32) -> Self;
395
396    /// Strict integer remainder. Computes `self % rhs`, panicking if
397    /// the division results in overflow.
398    fn strict_rem(self, rhs: Self) -> Self;
399
400    /// Strict Euclidean remainder. Computes `self.rem_euclid(rhs)`, panicking if
401    /// the division results in overflow.
402    fn strict_rem_euclid(self, rhs: Self) -> Self;
403
404    /// Strict shift left. Computes `self << rhs`, panicking if `rhs` is larger
405    /// than or equal to the number of bits in `self`.
406    fn strict_shl(self, rhs: u32) -> Self;
407
408    /// Strict shift right. Computes `self >> rhs`, panicking if `rhs` is
409    /// larger than or equal to the number of bits in `self`.
410    fn strict_shr(self, rhs: u32) -> Self;
411
412    /// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
413    fn strict_sub(self, rhs: Self) -> Self;
414
415    /// Reverses the byte order of the integer.
416    fn swap_bytes(self) -> Self;
417
418    /// Converts `self` to big endian from the target's endianness.
419    fn to_be(self) -> Self;
420
421    /// Converts `self` to little endian from the target's endianness.
422    fn to_le(self) -> Self;
423
424    /// Returns the number of trailing ones in the binary representation of `self`.
425    fn trailing_ones(self) -> u32;
426
427    /// Returns the number of trailing zeros in the binary representation of `self`.
428    fn trailing_zeros(self) -> u32;
429
430    /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`.
431    fn unbounded_shl(self, rhs: u32) -> Self;
432
433    /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`.
434    fn unbounded_shr(self, rhs: u32) -> Self;
435
436    /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the boundary of the
437    /// type.
438    fn wrapping_add(self, rhs: Self) -> Self;
439
440    /// Wrapping (modular) division. Computes `self / rhs`, wrapping around at the boundary of the
441    /// type.
442    fn wrapping_div(self, rhs: Self) -> Self;
443
444    /// Wrapping Euclidean division. Computes `self.div_euclid(rhs)`, wrapping around at the
445    /// boundary of the type.
446    fn wrapping_div_euclid(self, rhs: Self) -> Self;
447
448    /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at the boundary
449    /// of the type.
450    fn wrapping_mul(self, rhs: Self) -> Self;
451
452    /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary of the type.
453    fn wrapping_neg(self) -> Self;
454
455    /// Wrapping (modular) exponentiation. Computes `self.pow(exp)`, wrapping around at the
456    /// boundary of the type.
457    fn wrapping_pow(self, exp: u32) -> Self;
458
459    /// Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the boundary of the
460    /// type.
461    fn wrapping_rem(self, rhs: Self) -> Self;
462
463    /// Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping around at the
464    /// boundary of the type.
465    fn wrapping_rem_euclid(self, rhs: Self) -> Self;
466
467    /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where mask removes any
468    /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
469    fn wrapping_shl(self, rhs: u32) -> Self;
470
471    /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where mask removes any
472    /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
473    fn wrapping_shr(self, rhs: u32) -> Self;
474
475    /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the boundary of
476    /// the type.
477    fn wrapping_sub(self, rhs: Self) -> Self;
478
479    /// Unchecked integer addition. Computes `self + rhs`, assuming overflow cannot occur.
480    ///
481    /// # Safety
482    ///
483    /// This results in undefined behavior when `self + rhs > Self::MAX` or `self + rhs <
484    /// Self::MIN`, i.e. when [`checked_add`][Self::checked_add] would return `None`.
485    unsafe fn unchecked_add(self, rhs: Self) -> Self;
486
487    /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow cannot occur.
488    ///
489    /// # Safety
490    ///
491    /// This results in undefined behavior when `self * rhs > Self::MAX` or `self * rhs <
492    /// Self::MIN`, i.e. when [`checked_mul`][Self::checked_mul] would return `None`.
493    unsafe fn unchecked_mul(self, rhs: Self) -> Self;
494
495    /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow cannot occur.
496    ///
497    /// # Safety
498    ///
499    /// This results in undefined behavior when `self - rhs > Self::MAX` or `self - rhs <
500    /// Self::MIN`, i.e. when [`checked_sub`][Self::checked_sub] would return `None`.
501    unsafe fn unchecked_sub(self, rhs: Self) -> Self;
502}
503
504/// Trait for references to primitive integer types ([`PrimitiveInteger`]).
505///
506/// This enables traits like the standard operators in generic code,
507/// e.g. `where &T: PrimitiveIntegerRef<T>`.
508pub trait PrimitiveIntegerRef<T>:
509    PrimitiveNumberRef<T>
510    + core::cmp::Eq
511    + core::cmp::Ord
512    + core::fmt::Binary
513    + core::fmt::LowerHex
514    + core::fmt::Octal
515    + core::fmt::UpperHex
516    + core::hash::Hash
517    + core::ops::BitAnd<T, Output = T>
518    + core::ops::BitOr<T, Output = T>
519    + core::ops::BitXor<T, Output = T>
520    + core::ops::Not<Output = T>
521    + core::ops::Shl<T, Output = T>
522    + core::ops::Shl<i8, Output = T>
523    + core::ops::Shl<i16, Output = T>
524    + core::ops::Shl<i32, Output = T>
525    + core::ops::Shl<i64, Output = T>
526    + core::ops::Shl<i128, Output = T>
527    + core::ops::Shl<isize, Output = T>
528    + core::ops::Shl<u8, Output = T>
529    + core::ops::Shl<u16, Output = T>
530    + core::ops::Shl<u32, Output = T>
531    + core::ops::Shl<u64, Output = T>
532    + core::ops::Shl<u128, Output = T>
533    + core::ops::Shl<usize, Output = T>
534    + core::ops::Shr<T, Output = T>
535    + core::ops::Shr<i8, Output = T>
536    + core::ops::Shr<i16, Output = T>
537    + core::ops::Shr<i32, Output = T>
538    + core::ops::Shr<i64, Output = T>
539    + core::ops::Shr<i128, Output = T>
540    + core::ops::Shr<isize, Output = T>
541    + core::ops::Shr<u8, Output = T>
542    + core::ops::Shr<u16, Output = T>
543    + core::ops::Shr<u32, Output = T>
544    + core::ops::Shr<u64, Output = T>
545    + core::ops::Shr<u128, Output = T>
546    + core::ops::Shr<usize, Output = T>
547    + for<'a> core::ops::BitAnd<&'a T, Output = T>
548    + for<'a> core::ops::BitOr<&'a T, Output = T>
549    + for<'a> core::ops::BitXor<&'a T, Output = T>
550    + for<'a> core::ops::Shl<&'a T, Output = T>
551    + for<'a> core::ops::Shl<&'a i8, Output = T>
552    + for<'a> core::ops::Shl<&'a i16, Output = T>
553    + for<'a> core::ops::Shl<&'a i32, Output = T>
554    + for<'a> core::ops::Shl<&'a i64, Output = T>
555    + for<'a> core::ops::Shl<&'a i128, Output = T>
556    + for<'a> core::ops::Shl<&'a isize, Output = T>
557    + for<'a> core::ops::Shl<&'a u8, Output = T>
558    + for<'a> core::ops::Shl<&'a u16, Output = T>
559    + for<'a> core::ops::Shl<&'a u32, Output = T>
560    + for<'a> core::ops::Shl<&'a u64, Output = T>
561    + for<'a> core::ops::Shl<&'a u128, Output = T>
562    + for<'a> core::ops::Shl<&'a usize, Output = T>
563    + for<'a> core::ops::Shr<&'a T, Output = T>
564    + for<'a> core::ops::Shr<&'a i8, Output = T>
565    + for<'a> core::ops::Shr<&'a i16, Output = T>
566    + for<'a> core::ops::Shr<&'a i32, Output = T>
567    + for<'a> core::ops::Shr<&'a i64, Output = T>
568    + for<'a> core::ops::Shr<&'a i128, Output = T>
569    + for<'a> core::ops::Shr<&'a isize, Output = T>
570    + for<'a> core::ops::Shr<&'a u8, Output = T>
571    + for<'a> core::ops::Shr<&'a u16, Output = T>
572    + for<'a> core::ops::Shr<&'a u32, Output = T>
573    + for<'a> core::ops::Shr<&'a u64, Output = T>
574    + for<'a> core::ops::Shr<&'a u128, Output = T>
575    + for<'a> core::ops::Shr<&'a usize, Output = T>
576{
577}
578
579macro_rules! impl_integer {
580    ($($Integer:ident),*) => {$(
581        impl PrimitiveInteger for $Integer {
582            use_consts!(Self::{
583                BITS: u32,
584                MAX: Self,
585                MIN: Self,
586            });
587
588            forward! {
589                fn from_be(value: Self) -> Self;
590                fn from_le(value: Self) -> Self;
591                fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
592            }
593            forward! {
594                fn checked_add(self, rhs: Self) -> Option<Self>;
595                fn checked_div(self, rhs: Self) -> Option<Self>;
596                fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
597                fn checked_ilog(self, base: Self) -> Option<u32>;
598                fn checked_ilog10(self) -> Option<u32>;
599                fn checked_ilog2(self) -> Option<u32>;
600                fn checked_mul(self, rhs: Self) -> Option<Self>;
601                fn checked_neg(self) -> Option<Self>;
602                fn checked_pow(self, exp: u32) -> Option<Self>;
603                fn checked_rem(self, rhs: Self) -> Option<Self>;
604                fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
605                fn checked_shl(self, rhs: u32) -> Option<Self>;
606                fn checked_shr(self, rhs: u32) -> Option<Self>;
607                fn checked_sub(self, rhs: Self) -> Option<Self>;
608                fn count_ones(self) -> u32;
609                fn count_zeros(self) -> u32;
610                fn div_euclid(self, rhs: Self) -> Self;
611                fn ilog(self, base: Self) -> u32;
612                fn ilog10(self) -> u32;
613                fn ilog2(self) -> u32;
614                fn isqrt(self) -> Self;
615                fn leading_ones(self) -> u32;
616                fn leading_zeros(self) -> u32;
617                fn overflowing_add(self, rhs: Self) -> (Self, bool);
618                fn overflowing_div(self, rhs: Self) -> (Self, bool);
619                fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
620                fn overflowing_mul(self, rhs: Self) -> (Self, bool);
621                fn overflowing_neg(self) -> (Self, bool);
622                fn overflowing_pow(self, exp: u32) -> (Self, bool);
623                fn overflowing_rem(self, rhs: Self) -> (Self, bool);
624                fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool);
625                fn overflowing_shl(self, rhs: u32) -> (Self, bool);
626                fn overflowing_shr(self, rhs: u32) -> (Self, bool);
627                fn overflowing_sub(self, rhs: Self) -> (Self, bool);
628                fn pow(self, exp: u32) -> Self;
629                fn rem_euclid(self, rhs: Self) -> Self;
630                fn reverse_bits(self) -> Self;
631                fn rotate_left(self, n: u32) -> Self;
632                fn rotate_right(self, n: u32) -> Self;
633                fn saturating_add(self, rhs: Self) -> Self;
634                fn saturating_div(self, rhs: Self) -> Self;
635                fn saturating_mul(self, rhs: Self) -> Self;
636                fn saturating_pow(self, exp: u32) -> Self;
637                fn saturating_sub(self, rhs: Self) -> Self;
638                fn strict_add(self, rhs: Self) -> Self;
639                fn strict_div(self, rhs: Self) -> Self;
640                fn strict_div_euclid(self, rhs: Self) -> Self;
641                fn strict_mul(self, rhs: Self) -> Self;
642                fn strict_neg(self) -> Self;
643                fn strict_pow(self, exp: u32) -> Self;
644                fn strict_rem(self, rhs: Self) -> Self;
645                fn strict_rem_euclid(self, rhs: Self) -> Self;
646                fn strict_shl(self, rhs: u32) -> Self;
647                fn strict_shr(self, rhs: u32) -> Self;
648                fn strict_sub(self, rhs: Self) -> Self;
649                fn swap_bytes(self) -> Self;
650                fn to_be(self) -> Self;
651                fn to_le(self) -> Self;
652                fn trailing_ones(self) -> u32;
653                fn trailing_zeros(self) -> u32;
654                fn unbounded_shl(self, rhs: u32) -> Self;
655                fn unbounded_shr(self, rhs: u32) -> Self;
656                fn wrapping_add(self, rhs: Self) -> Self;
657                fn wrapping_div(self, rhs: Self) -> Self;
658                fn wrapping_div_euclid(self, rhs: Self) -> Self;
659                fn wrapping_mul(self, rhs: Self) -> Self;
660                fn wrapping_neg(self) -> Self;
661                fn wrapping_pow(self, exp: u32) -> Self;
662                fn wrapping_rem(self, rhs: Self) -> Self;
663                fn wrapping_rem_euclid(self, rhs: Self) -> Self;
664                fn wrapping_shl(self, rhs: u32) -> Self;
665                fn wrapping_shr(self, rhs: u32) -> Self;
666                fn wrapping_sub(self, rhs: Self) -> Self;
667            }
668            forward! {
669                unsafe fn unchecked_add(self, rhs: Self) -> Self;
670                unsafe fn unchecked_mul(self, rhs: Self) -> Self;
671                unsafe fn unchecked_sub(self, rhs: Self) -> Self;
672            }
673        }
674
675        impl PrimitiveIntegerRef<$Integer> for &$Integer {}
676    )*}
677}
678
679impl_integer!(i8, i16, i32, i64, i128, isize);
680impl_integer!(u8, u16, u32, u64, u128, usize);