num_primitive/
integer.rs

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