Skip to main content

num_primitive/
integer.rs

1use core::fmt::NumBuffer;
2use core::num::{NonZero, ParseIntError, TryFromIntError};
3
4use crate::{PrimitiveError, PrimitiveNumber, PrimitiveNumberRef};
5
6trait Sealed {}
7
8/// Trait for all primitive [integer types], including the supertrait [`PrimitiveNumber`].
9///
10/// This encapsulates trait implementations, constants, and inherent methods that are common among
11/// all of the primitive integer types: [`i8`], [`i16`], [`i32`], [`i64`], [`i128`], [`isize`],
12/// [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], and [`usize`].
13///
14/// See the corresponding items on the individual types for more documentation and examples.
15///
16/// This trait is sealed with a private trait to prevent downstream implementations, so we may
17/// continue to expand along with the standard library without worrying about breaking changes for
18/// implementors.
19///
20/// [integer types]: https://doc.rust-lang.org/reference/types/numeric.html#r-type.numeric.int
21///
22/// # Examples
23///
24/// ```
25/// use num_primitive::PrimitiveInteger;
26///
27/// fn div_rem<T: PrimitiveInteger>(a: T, b: T) -> (T, T) {
28///     (a / b, a % b)
29/// }
30///
31/// fn div_rem_euclid<T: PrimitiveInteger>(a: T, b: T) -> (T, T) {
32///     (a.div_euclid(b), a.rem_euclid(b))
33/// }
34///
35/// assert_eq!(div_rem::<u8>(48, 18), (2, 12));
36/// assert_eq!(div_rem::<i8>(-48, 18), (-2, -12));
37///
38/// assert_eq!(div_rem_euclid::<u8>(48, 18), (2, 12));
39/// assert_eq!(div_rem_euclid::<i8>(-48, 18), (-3, 6));
40/// ```
41///
42pub trait PrimitiveInteger:
43    PrimitiveNumber
44    + core::cmp::Eq
45    + core::cmp::Ord
46    + core::convert::From<Self::NonZero>
47    + core::convert::TryFrom<i8, Error: PrimitiveError>
48    + core::convert::TryFrom<i16, Error: PrimitiveError>
49    + core::convert::TryFrom<i32, Error: PrimitiveError>
50    + core::convert::TryFrom<i64, Error: PrimitiveError>
51    + core::convert::TryFrom<i128, Error: PrimitiveError>
52    + core::convert::TryFrom<isize, Error: PrimitiveError>
53    + core::convert::TryFrom<u8, Error: PrimitiveError>
54    + core::convert::TryFrom<u16, Error: PrimitiveError>
55    + core::convert::TryFrom<u32, Error: PrimitiveError>
56    + core::convert::TryFrom<u64, Error: PrimitiveError>
57    + core::convert::TryFrom<u128, Error: PrimitiveError>
58    + core::convert::TryFrom<usize, Error: PrimitiveError>
59    + core::convert::TryInto<Self::NonZero, Error = TryFromIntError>
60    + core::convert::TryInto<i8, Error: PrimitiveError>
61    + core::convert::TryInto<i16, Error: PrimitiveError>
62    + core::convert::TryInto<i32, Error: PrimitiveError>
63    + core::convert::TryInto<i64, Error: PrimitiveError>
64    + core::convert::TryInto<i128, Error: PrimitiveError>
65    + core::convert::TryInto<isize, Error: PrimitiveError>
66    + core::convert::TryInto<u8, Error: PrimitiveError>
67    + core::convert::TryInto<u16, Error: PrimitiveError>
68    + core::convert::TryInto<u32, Error: PrimitiveError>
69    + core::convert::TryInto<u64, Error: PrimitiveError>
70    + core::convert::TryInto<u128, Error: PrimitiveError>
71    + core::convert::TryInto<usize, Error: PrimitiveError>
72    + core::fmt::Binary
73    + core::fmt::LowerHex
74    + core::fmt::Octal
75    + core::fmt::UpperHex
76    + core::hash::Hash
77    + core::ops::BitAnd<Self, Output = Self>
78    + core::ops::BitAndAssign<Self>
79    + core::ops::BitOr<Self, Output = Self>
80    + core::ops::BitOr<Self::NonZero, Output = Self::NonZero>
81    + core::ops::BitOrAssign<Self>
82    + core::ops::BitXor<Self, Output = Self>
83    + core::ops::BitXorAssign<Self>
84    + core::ops::Not<Output = Self>
85    + core::ops::Shl<Self, Output = Self>
86    + core::ops::Shl<i8, Output = Self>
87    + core::ops::Shl<i16, Output = Self>
88    + core::ops::Shl<i32, Output = Self>
89    + core::ops::Shl<i64, Output = Self>
90    + core::ops::Shl<i128, Output = Self>
91    + core::ops::Shl<isize, Output = Self>
92    + core::ops::Shl<u8, Output = Self>
93    + core::ops::Shl<u16, Output = Self>
94    + core::ops::Shl<u32, Output = Self>
95    + core::ops::Shl<u64, Output = Self>
96    + core::ops::Shl<u128, Output = Self>
97    + core::ops::Shl<usize, Output = Self>
98    + core::ops::ShlAssign<Self>
99    + core::ops::ShlAssign<i8>
100    + core::ops::ShlAssign<i16>
101    + core::ops::ShlAssign<i32>
102    + core::ops::ShlAssign<i64>
103    + core::ops::ShlAssign<i128>
104    + core::ops::ShlAssign<isize>
105    + core::ops::ShlAssign<u8>
106    + core::ops::ShlAssign<u16>
107    + core::ops::ShlAssign<u32>
108    + core::ops::ShlAssign<u64>
109    + core::ops::ShlAssign<u128>
110    + core::ops::ShlAssign<usize>
111    + core::ops::Shr<Self, Output = Self>
112    + core::ops::Shr<i8, Output = Self>
113    + core::ops::Shr<i16, Output = Self>
114    + core::ops::Shr<i32, Output = Self>
115    + core::ops::Shr<i64, Output = Self>
116    + core::ops::Shr<i128, Output = Self>
117    + core::ops::Shr<isize, Output = Self>
118    + core::ops::Shr<u8, Output = Self>
119    + core::ops::Shr<u16, Output = Self>
120    + core::ops::Shr<u32, Output = Self>
121    + core::ops::Shr<u64, Output = Self>
122    + core::ops::Shr<u128, Output = Self>
123    + core::ops::Shr<usize, Output = Self>
124    + core::ops::ShrAssign<Self>
125    + core::ops::ShrAssign<i8>
126    + core::ops::ShrAssign<i16>
127    + core::ops::ShrAssign<i32>
128    + core::ops::ShrAssign<i64>
129    + core::ops::ShrAssign<i128>
130    + core::ops::ShrAssign<isize>
131    + core::ops::ShrAssign<u8>
132    + core::ops::ShrAssign<u16>
133    + core::ops::ShrAssign<u32>
134    + core::ops::ShrAssign<u64>
135    + core::ops::ShrAssign<u128>
136    + core::ops::ShrAssign<usize>
137    + core::str::FromStr<Err = ParseIntError>
138    + for<'a> core::ops::BitAnd<&'a Self, Output = Self>
139    + for<'a> core::ops::BitAndAssign<&'a Self>
140    + for<'a> core::ops::BitOr<&'a Self, Output = Self>
141    + for<'a> core::ops::BitOrAssign<&'a Self>
142    + for<'a> core::ops::BitXor<&'a Self, Output = Self>
143    + for<'a> core::ops::BitXorAssign<&'a Self>
144    + for<'a> core::ops::Shl<&'a Self, Output = Self>
145    + for<'a> core::ops::Shl<&'a i8, Output = Self>
146    + for<'a> core::ops::Shl<&'a i16, Output = Self>
147    + for<'a> core::ops::Shl<&'a i32, Output = Self>
148    + for<'a> core::ops::Shl<&'a i64, Output = Self>
149    + for<'a> core::ops::Shl<&'a i128, Output = Self>
150    + for<'a> core::ops::Shl<&'a isize, Output = Self>
151    + for<'a> core::ops::Shl<&'a u8, Output = Self>
152    + for<'a> core::ops::Shl<&'a u16, Output = Self>
153    + for<'a> core::ops::Shl<&'a u32, Output = Self>
154    + for<'a> core::ops::Shl<&'a u64, Output = Self>
155    + for<'a> core::ops::Shl<&'a u128, Output = Self>
156    + for<'a> core::ops::Shl<&'a usize, Output = Self>
157    + for<'a> core::ops::ShlAssign<&'a Self>
158    + for<'a> core::ops::ShlAssign<&'a i8>
159    + for<'a> core::ops::ShlAssign<&'a i16>
160    + for<'a> core::ops::ShlAssign<&'a i32>
161    + for<'a> core::ops::ShlAssign<&'a i64>
162    + for<'a> core::ops::ShlAssign<&'a i128>
163    + for<'a> core::ops::ShlAssign<&'a isize>
164    + for<'a> core::ops::ShlAssign<&'a u8>
165    + for<'a> core::ops::ShlAssign<&'a u16>
166    + for<'a> core::ops::ShlAssign<&'a u32>
167    + for<'a> core::ops::ShlAssign<&'a u64>
168    + for<'a> core::ops::ShlAssign<&'a u128>
169    + for<'a> core::ops::ShlAssign<&'a usize>
170    + for<'a> core::ops::Shr<&'a Self, Output = Self>
171    + for<'a> core::ops::Shr<&'a i8, Output = Self>
172    + for<'a> core::ops::Shr<&'a i16, Output = Self>
173    + for<'a> core::ops::Shr<&'a i32, Output = Self>
174    + for<'a> core::ops::Shr<&'a i64, Output = Self>
175    + for<'a> core::ops::Shr<&'a i128, Output = Self>
176    + for<'a> core::ops::Shr<&'a isize, Output = Self>
177    + for<'a> core::ops::Shr<&'a u8, Output = Self>
178    + for<'a> core::ops::Shr<&'a u16, Output = Self>
179    + for<'a> core::ops::Shr<&'a u32, Output = Self>
180    + for<'a> core::ops::Shr<&'a u64, Output = Self>
181    + for<'a> core::ops::Shr<&'a u128, Output = Self>
182    + for<'a> core::ops::Shr<&'a usize, Output = Self>
183    + for<'a> core::ops::ShrAssign<&'a Self>
184    + for<'a> core::ops::ShrAssign<&'a i8>
185    + for<'a> core::ops::ShrAssign<&'a i16>
186    + for<'a> core::ops::ShrAssign<&'a i32>
187    + for<'a> core::ops::ShrAssign<&'a i64>
188    + for<'a> core::ops::ShrAssign<&'a i128>
189    + for<'a> core::ops::ShrAssign<&'a isize>
190    + for<'a> core::ops::ShrAssign<&'a u8>
191    + for<'a> core::ops::ShrAssign<&'a u16>
192    + for<'a> core::ops::ShrAssign<&'a u32>
193    + for<'a> core::ops::ShrAssign<&'a u64>
194    + for<'a> core::ops::ShrAssign<&'a u128>
195    + for<'a> core::ops::ShrAssign<&'a usize>
196{
197    /// The non-zero integer type wrapping this primitive integer.
198    ///
199    /// This is always [`core::num::NonZero<Self>`].
200    type NonZero: NonZeroPrimitiveInteger<Integer = Self>;
201
202    /// The buffer type for [`format_into`][Self::format_into].
203    ///
204    /// This is always [`core::fmt::NumBuffer<Self>`].
205    type NumBuffer: PrimitiveNumBuffer;
206
207    /// The size of this integer type in bits.
208    const BITS: u32;
209
210    /// The largest value that can be represented by this integer type.
211    const MAX: Self;
212
213    /// The smallest value that can be represented by this integer type.
214    const MIN: Self;
215
216    /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
217    fn checked_add(self, rhs: Self) -> Option<Self>;
218
219    /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0` or the
220    /// division results in overflow.
221    fn checked_div(self, rhs: Self) -> Option<Self>;
222
223    /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None` if `rhs == 0`
224    /// or the division results in overflow.
225    fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
226
227    /// Returns the logarithm of the number with respect to an arbitrary base, rounded down.
228    /// Returns `None` if the number is negative or zero, or if the base is not at least 2.
229    fn checked_ilog(self, base: Self) -> Option<u32>;
230
231    /// Returns the base 10 logarithm of the number, rounded down. Returns `None` if the number is
232    /// negative or zero.
233    fn checked_ilog10(self) -> Option<u32>;
234
235    /// Returns the base 2 logarithm of the number, rounded down. Returns `None` if the number is
236    /// negative or zero.
237    fn checked_ilog2(self) -> Option<u32>;
238
239    /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow
240    /// occurred.
241    fn checked_mul(self, rhs: Self) -> Option<Self>;
242
243    /// Checked negation. Computes -self, returning `None` if `self == MIN` for signed integers,
244    /// or for any non-zero unsigned integer.
245    fn checked_neg(self) -> Option<Self>;
246
247    /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if overflow occurred.
248    fn checked_pow(self, exp: u32) -> Option<Self>;
249
250    /// Checked integer remainder. Computes `self % rhs`, returning `None` if `rhs == 0` or the
251    /// division results in overflow.
252    fn checked_rem(self, rhs: Self) -> Option<Self>;
253
254    /// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None` if `rhs ==
255    /// 0` or the division results in overflow.
256    fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
257
258    /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger than or
259    /// equal to the number of bits in `self`.
260    fn checked_shl(self, rhs: u32) -> Option<Self>;
261
262    /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is larger than or
263    /// equal to the number of bits in `self`.
264    fn checked_shr(self, rhs: u32) -> Option<Self>;
265
266    /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
267    fn checked_sub(self, rhs: Self) -> Option<Self>;
268
269    /// Returns the number of ones in the binary representation of `self`.
270    fn count_ones(self) -> u32;
271
272    /// Returns the number of zeros in the binary representation of `self`.
273    fn count_zeros(self) -> u32;
274
275    /// Calculates the quotient of Euclidean division of `self` by `rhs`. This computes the integer
276    /// `q` such that `self = q * rhs + r`, with `r = self.rem_euclid(rhs)` and `0 <= r <
277    /// abs(rhs)`.
278    fn div_euclid(self, rhs: Self) -> Self;
279
280    /// Writes `self` in decimal format into the given buffer, and returns it as a borrowed string.
281    fn format_into(self, buf: &mut Self::NumBuffer) -> &str;
282
283    /// Converts an integer from big endian to the target's endianness.
284    fn from_be(value: Self) -> Self;
285
286    /// Converts an integer from little endian to the target's endianness.
287    fn from_le(value: Self) -> Self;
288
289    /// Parses an integer from a string slice with digits in a given base.
290    fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
291
292    /// Returns the index of the highest bit set to one in `self`, or `None` if `self` is `0`.
293    fn highest_one(self) -> Option<u32>;
294
295    /// Returns the logarithm of the number with respect to an arbitrary base, rounded down.
296    fn ilog(self, base: Self) -> u32;
297
298    /// Returns the base 10 logarithm of the number, rounded down.
299    fn ilog10(self) -> u32;
300
301    /// Returns the base 2 logarithm of the number, rounded down.
302    fn ilog2(self) -> u32;
303
304    /// Returns `self` with only the most significant bit set, or `0` if the input is `0`.
305    fn isolate_highest_one(self) -> Self;
306
307    /// Returns `self` with only the least significant bit set, or `0` if the input is `0`.
308    fn isolate_lowest_one(self) -> Self;
309
310    /// Returns the square root of the number, rounded down.
311    fn isqrt(self) -> Self;
312
313    /// Returns the number of leading ones in the binary representation of `self`.
314    fn leading_ones(self) -> u32;
315
316    /// Returns the number of leading zeros in the binary representation of `self`.
317    fn leading_zeros(self) -> u32;
318
319    /// Returns the index of the lowest bit set to one in `self`, or `None` if `self` is `0`.
320    fn lowest_one(self) -> Option<u32>;
321
322    /// Calculates `self + rhs`. Returns a tuple of the addition along with a boolean indicating
323    /// whether an arithmetic overflow would occur.
324    fn overflowing_add(self, rhs: Self) -> (Self, bool);
325
326    /// Calculates the divisor when `self` is divided by `rhs`. Returns a tuple of the divisor
327    /// along with a boolean indicating whether an arithmetic overflow would occur.
328    fn overflowing_div(self, rhs: Self) -> (Self, bool);
329
330    /// Calculates the quotient of Euclidean division `self`.div_euclid(rhs). Returns a tuple of
331    /// the divisor along with a boolean indicating whether an arithmetic overflow would occur.
332    fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
333
334    /// Calculates the multiplication of `self` and `rhs`. Returns a tuple of the multiplication
335    /// along with a boolean indicating whether an arithmetic overflow would occur.
336    fn overflowing_mul(self, rhs: Self) -> (Self, bool);
337
338    /// Negates self, overflowing if this is equal to the minimum value. Returns a tuple of the
339    /// negated version of `self` along with a boolean indicating whether an overflow happened.
340    fn overflowing_neg(self) -> (Self, bool);
341
342    /// Raises `self` to the power of `exp`, using exponentiation by squaring. Returns a tuple of
343    /// the exponentiation along with a bool indicating whether an overflow happened.
344    fn overflowing_pow(self, exp: u32) -> (Self, bool);
345
346    /// Calculates the remainder when `self` is divided by `rhs`. Returns a tuple of the remainder
347    /// after dividing along with a boolean indicating whether an arithmetic overflow would occur.
348    fn overflowing_rem(self, rhs: Self) -> (Self, bool);
349
350    /// Overflowing Euclidean remainder. Calculates `self`.rem_euclid(rhs). Returns a tuple of the
351    /// remainder after dividing along with a boolean indicating whether an arithmetic overflow
352    /// would occur.
353    fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool);
354
355    /// Shifts `self` left by `rhs` bits. Returns a tuple of the shifted version of `self` along
356    /// with a boolean indicating whether the shift value was larger than or equal to the number of
357    /// bits.
358    fn overflowing_shl(self, rhs: u32) -> (Self, bool);
359
360    /// Shifts `self` right by `rhs` bits. Returns a tuple of the shifted version of `self` along
361    /// with a boolean indicating whether the shift value was larger than or equal to the number of
362    /// bits.
363    fn overflowing_shr(self, rhs: u32) -> (Self, bool);
364
365    /// Calculates `self - rhs`. Returns a tuple of the subtraction along with a boolean indicating
366    /// whether an arithmetic overflow would occur.
367    fn overflowing_sub(self, rhs: Self) -> (Self, bool);
368
369    /// Raises `self` to the power of `exp`, using exponentiation by squaring.
370    fn pow(self, exp: u32) -> Self;
371
372    /// Calculates the least nonnegative remainder of `self (mod rhs)`. This is done as if by the
373    /// Euclidean division algorithm – given `r = self.rem_euclid(rhs)`, the result satisfies `self
374    /// = rhs * self.div_euclid(rhs) + r` and `0 <= r < abs(rhs)`.
375    fn rem_euclid(self, rhs: Self) -> Self;
376
377    /// Reverses the order of bits in the integer.
378    fn reverse_bits(self) -> Self;
379
380    /// Shifts the bits to the left by a specified amount, n, wrapping the truncated bits to the
381    /// end of the resulting integer.
382    fn rotate_left(self, n: u32) -> Self;
383
384    /// Shifts the bits to the right by a specified amount, n, wrapping the truncated bits to the
385    /// beginning of the resulting integer.
386    fn rotate_right(self, n: u32) -> Self;
387
388    /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric bounds
389    /// instead of overflowing.
390    fn saturating_add(self, rhs: Self) -> Self;
391
392    /// Saturating integer division. Computes `self / rhs`, saturating at the numeric bounds
393    /// instead of overflowing.
394    fn saturating_div(self, rhs: Self) -> Self;
395
396    /// Saturating integer multiplication. Computes `self * rhs`, saturating at the numeric bounds
397    /// instead of overflowing.
398    fn saturating_mul(self, rhs: Self) -> Self;
399
400    /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating at the numeric
401    /// bounds instead of overflowing.
402    fn saturating_pow(self, exp: u32) -> Self;
403
404    /// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric bounds
405    /// instead of overflowing.
406    fn saturating_sub(self, rhs: Self) -> Self;
407
408    /// Strict integer addition. Computes `self + rhs`, panicking if overflow occurred.
409    fn strict_add(self, rhs: Self) -> Self;
410
411    /// Strict integer division. Computes `self / rhs`, panicking if overflow occurred.
412    fn strict_div(self, rhs: Self) -> Self;
413
414    /// Strict Euclidean division. Computes `self.div_euclid(rhs)`, panicking if overflow occurred.
415    fn strict_div_euclid(self, rhs: Self) -> Self;
416
417    /// Strict integer multiplication. Computes `self * rhs`, panicking if overflow occurred.
418    fn strict_mul(self, rhs: Self) -> Self;
419
420    /// Strict negation. Computes `-self`, panicking if `self == MIN` for signed integers,
421    /// or for any non-zero unsigned integer.
422    fn strict_neg(self) -> Self;
423
424    /// Strict exponentiation. Computes `self.pow(exp)`, panicking if overflow occurred.
425    fn strict_pow(self, exp: u32) -> Self;
426
427    /// Strict integer remainder. Computes `self % rhs`, panicking if
428    /// the division results in overflow.
429    fn strict_rem(self, rhs: Self) -> Self;
430
431    /// Strict Euclidean remainder. Computes `self.rem_euclid(rhs)`, panicking if
432    /// the division results in overflow.
433    fn strict_rem_euclid(self, rhs: Self) -> Self;
434
435    /// Strict shift left. Computes `self << rhs`, panicking if `rhs` is larger
436    /// than or equal to the number of bits in `self`.
437    fn strict_shl(self, rhs: u32) -> Self;
438
439    /// Strict shift right. Computes `self >> rhs`, panicking if `rhs` is
440    /// larger than or equal to the number of bits in `self`.
441    fn strict_shr(self, rhs: u32) -> Self;
442
443    /// Strict integer subtraction. Computes `self - rhs`, panicking if overflow occurred.
444    fn strict_sub(self, rhs: Self) -> Self;
445
446    /// Reverses the byte order of the integer.
447    fn swap_bytes(self) -> Self;
448
449    /// Converts `self` to big endian from the target's endianness.
450    fn to_be(self) -> Self;
451
452    /// Converts `self` to little endian from the target's endianness.
453    fn to_le(self) -> Self;
454
455    /// Returns the number of trailing ones in the binary representation of `self`.
456    fn trailing_ones(self) -> u32;
457
458    /// Returns the number of trailing zeros in the binary representation of `self`.
459    fn trailing_zeros(self) -> u32;
460
461    /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`.
462    fn unbounded_shl(self, rhs: u32) -> Self;
463
464    /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`.
465    fn unbounded_shr(self, rhs: u32) -> Self;
466
467    /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the boundary of the
468    /// type.
469    fn wrapping_add(self, rhs: Self) -> Self;
470
471    /// Wrapping (modular) division. Computes `self / rhs`, wrapping around at the boundary of the
472    /// type.
473    fn wrapping_div(self, rhs: Self) -> Self;
474
475    /// Wrapping Euclidean division. Computes `self.div_euclid(rhs)`, wrapping around at the
476    /// boundary of the type.
477    fn wrapping_div_euclid(self, rhs: Self) -> Self;
478
479    /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at the boundary
480    /// of the type.
481    fn wrapping_mul(self, rhs: Self) -> Self;
482
483    /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary of the type.
484    fn wrapping_neg(self) -> Self;
485
486    /// Wrapping (modular) exponentiation. Computes `self.pow(exp)`, wrapping around at the
487    /// boundary of the type.
488    fn wrapping_pow(self, exp: u32) -> Self;
489
490    /// Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the boundary of the
491    /// type.
492    fn wrapping_rem(self, rhs: Self) -> Self;
493
494    /// Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping around at the
495    /// boundary of the type.
496    fn wrapping_rem_euclid(self, rhs: Self) -> Self;
497
498    /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where mask removes any
499    /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
500    fn wrapping_shl(self, rhs: u32) -> Self;
501
502    /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where mask removes any
503    /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
504    fn wrapping_shr(self, rhs: u32) -> Self;
505
506    /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the boundary of
507    /// the type.
508    fn wrapping_sub(self, rhs: Self) -> Self;
509
510    /// Unchecked integer addition. Computes `self + rhs`, assuming overflow cannot occur.
511    ///
512    /// # Safety
513    ///
514    /// This results in undefined behavior when `self + rhs > Self::MAX` or `self + rhs <
515    /// Self::MIN`, i.e. when [`checked_add`][Self::checked_add] would return `None`.
516    unsafe fn unchecked_add(self, rhs: Self) -> Self;
517
518    /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow cannot occur.
519    ///
520    /// # Safety
521    ///
522    /// This results in undefined behavior when `self * rhs > Self::MAX` or `self * rhs <
523    /// Self::MIN`, i.e. when [`checked_mul`][Self::checked_mul] would return `None`.
524    unsafe fn unchecked_mul(self, rhs: Self) -> Self;
525
526    /// Unchecked shift left. Computes `self << rhs`, assuming that
527    /// `rhs` is less than the number of bits in `self`.
528    ///
529    /// # Safety
530    ///
531    /// This results in undefined behavior if `rhs` is larger than or equal to the number of bits
532    /// in `self`, i.e. when [`checked_shl`][Self::checked_shl] would return `None`.
533    unsafe fn unchecked_shl(self, rhs: u32) -> Self;
534
535    /// Unchecked shift right. Computes `self >> rhs`, assuming that
536    /// `rhs` is less than the number of bits in `self`.
537    ///
538    /// # Safety
539    ///
540    /// This results in undefined behavior if `rhs` is larger than or equal to the number of bits
541    /// in `self`, i.e. when [`checked_shr`][Self::checked_shr] would return `None`.
542    unsafe fn unchecked_shr(self, rhs: u32) -> Self;
543
544    /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow cannot occur.
545    ///
546    /// # Safety
547    ///
548    /// This results in undefined behavior when `self - rhs > Self::MAX` or `self - rhs <
549    /// Self::MIN`, i.e. when [`checked_sub`][Self::checked_sub] would return `None`.
550    unsafe fn unchecked_sub(self, rhs: Self) -> Self;
551}
552
553/// Trait for references to primitive integer types ([`PrimitiveInteger`]).
554///
555/// This enables traits like the standard operators in generic code,
556/// e.g. `where &T: PrimitiveIntegerRef<T>`.
557pub trait PrimitiveIntegerRef<T>:
558    PrimitiveNumberRef<T>
559    + core::cmp::Eq
560    + core::cmp::Ord
561    + core::fmt::Binary
562    + core::fmt::LowerHex
563    + core::fmt::Octal
564    + core::fmt::UpperHex
565    + core::hash::Hash
566    + core::ops::BitAnd<T, Output = T>
567    + core::ops::BitOr<T, Output = T>
568    + core::ops::BitXor<T, Output = T>
569    + core::ops::Not<Output = T>
570    + core::ops::Shl<T, Output = T>
571    + core::ops::Shl<i8, Output = T>
572    + core::ops::Shl<i16, Output = T>
573    + core::ops::Shl<i32, Output = T>
574    + core::ops::Shl<i64, Output = T>
575    + core::ops::Shl<i128, Output = T>
576    + core::ops::Shl<isize, Output = T>
577    + core::ops::Shl<u8, Output = T>
578    + core::ops::Shl<u16, Output = T>
579    + core::ops::Shl<u32, Output = T>
580    + core::ops::Shl<u64, Output = T>
581    + core::ops::Shl<u128, Output = T>
582    + core::ops::Shl<usize, Output = T>
583    + core::ops::Shr<T, Output = T>
584    + core::ops::Shr<i8, Output = T>
585    + core::ops::Shr<i16, Output = T>
586    + core::ops::Shr<i32, Output = T>
587    + core::ops::Shr<i64, Output = T>
588    + core::ops::Shr<i128, Output = T>
589    + core::ops::Shr<isize, Output = T>
590    + core::ops::Shr<u8, Output = T>
591    + core::ops::Shr<u16, Output = T>
592    + core::ops::Shr<u32, Output = T>
593    + core::ops::Shr<u64, Output = T>
594    + core::ops::Shr<u128, Output = T>
595    + core::ops::Shr<usize, Output = T>
596    + for<'a> core::ops::BitAnd<&'a T, Output = T>
597    + for<'a> core::ops::BitOr<&'a T, Output = T>
598    + for<'a> core::ops::BitXor<&'a T, Output = T>
599    + for<'a> core::ops::Shl<&'a T, Output = T>
600    + for<'a> core::ops::Shl<&'a i8, Output = T>
601    + for<'a> core::ops::Shl<&'a i16, Output = T>
602    + for<'a> core::ops::Shl<&'a i32, Output = T>
603    + for<'a> core::ops::Shl<&'a i64, Output = T>
604    + for<'a> core::ops::Shl<&'a i128, Output = T>
605    + for<'a> core::ops::Shl<&'a isize, Output = T>
606    + for<'a> core::ops::Shl<&'a u8, Output = T>
607    + for<'a> core::ops::Shl<&'a u16, Output = T>
608    + for<'a> core::ops::Shl<&'a u32, Output = T>
609    + for<'a> core::ops::Shl<&'a u64, Output = T>
610    + for<'a> core::ops::Shl<&'a u128, Output = T>
611    + for<'a> core::ops::Shl<&'a usize, Output = T>
612    + for<'a> core::ops::Shr<&'a T, Output = T>
613    + for<'a> core::ops::Shr<&'a i8, Output = T>
614    + for<'a> core::ops::Shr<&'a i16, Output = T>
615    + for<'a> core::ops::Shr<&'a i32, Output = T>
616    + for<'a> core::ops::Shr<&'a i64, Output = T>
617    + for<'a> core::ops::Shr<&'a i128, Output = T>
618    + for<'a> core::ops::Shr<&'a isize, Output = T>
619    + for<'a> core::ops::Shr<&'a u8, Output = T>
620    + for<'a> core::ops::Shr<&'a u16, Output = T>
621    + for<'a> core::ops::Shr<&'a u32, Output = T>
622    + for<'a> core::ops::Shr<&'a u64, Output = T>
623    + for<'a> core::ops::Shr<&'a u128, Output = T>
624    + for<'a> core::ops::Shr<&'a usize, Output = T>
625{
626}
627
628/// Trait for [`NonZero`] primitive integers.
629///
630/// This encapsulates trait implementations, constants, and inherent methods that are common among
631/// all of the implementations of `NonZero<T>`, where `T` is a [`PrimitiveInteger`].
632///
633/// See the corresponding items on the individual types for more documentation and examples.
634///
635/// This trait is sealed with a private trait to prevent downstream implementations, so we may
636/// continue to expand along with the standard library without worrying about breaking changes for
637/// implementors.
638///
639/// # Examples
640///
641/// ```
642/// use num_primitive::NonZeroPrimitiveInteger;
643/// use core::num::NonZero;
644///
645/// fn bits_and_zeros<T: NonZeroPrimitiveInteger>(n: T) -> (u32, u32, u32) {
646///     (T::BITS, n.leading_zeros(), n.trailing_zeros())
647/// }
648///
649/// assert_eq!(bits_and_zeros(NonZero::new(0b0010_1000u8).unwrap()), (8, 2, 3));
650/// assert_eq!(bits_and_zeros(NonZero::new(1i64).unwrap()), (64, 63, 0));
651/// ```
652#[expect(private_bounds)]
653pub trait NonZeroPrimitiveInteger:
654    'static
655    + Sealed
656    + core::cmp::Eq
657    + core::cmp::Ord
658    + core::convert::Into<Self::Integer>
659    + core::convert::TryFrom<Self::Integer, Error = TryFromIntError>
660    + core::convert::TryFrom<NonZero<i8>, Error: PrimitiveError>
661    + core::convert::TryFrom<NonZero<i16>, Error: PrimitiveError>
662    + core::convert::TryFrom<NonZero<i32>, Error: PrimitiveError>
663    + core::convert::TryFrom<NonZero<i64>, Error: PrimitiveError>
664    + core::convert::TryFrom<NonZero<i128>, Error: PrimitiveError>
665    + core::convert::TryFrom<NonZero<isize>, Error: PrimitiveError>
666    + core::convert::TryFrom<NonZero<u8>, Error: PrimitiveError>
667    + core::convert::TryFrom<NonZero<u16>, Error: PrimitiveError>
668    + core::convert::TryFrom<NonZero<u32>, Error: PrimitiveError>
669    + core::convert::TryFrom<NonZero<u64>, Error: PrimitiveError>
670    + core::convert::TryFrom<NonZero<u128>, Error: PrimitiveError>
671    + core::convert::TryFrom<NonZero<usize>, Error: PrimitiveError>
672    + core::convert::TryInto<NonZero<i8>, Error: PrimitiveError>
673    + core::convert::TryInto<NonZero<i16>, Error: PrimitiveError>
674    + core::convert::TryInto<NonZero<i32>, Error: PrimitiveError>
675    + core::convert::TryInto<NonZero<i64>, Error: PrimitiveError>
676    + core::convert::TryInto<NonZero<i128>, Error: PrimitiveError>
677    + core::convert::TryInto<NonZero<isize>, Error: PrimitiveError>
678    + core::convert::TryInto<NonZero<u8>, Error: PrimitiveError>
679    + core::convert::TryInto<NonZero<u16>, Error: PrimitiveError>
680    + core::convert::TryInto<NonZero<u32>, Error: PrimitiveError>
681    + core::convert::TryInto<NonZero<u64>, Error: PrimitiveError>
682    + core::convert::TryInto<NonZero<u128>, Error: PrimitiveError>
683    + core::convert::TryInto<NonZero<usize>, Error: PrimitiveError>
684    + core::fmt::Binary
685    + core::fmt::Debug
686    + core::fmt::Display
687    + core::fmt::LowerExp
688    + core::fmt::LowerHex
689    + core::fmt::Octal
690    + core::fmt::UpperExp
691    + core::fmt::UpperHex
692    + core::hash::Hash
693    + core::marker::Copy
694    + core::marker::Send
695    + core::marker::Sync
696    + core::marker::Unpin
697    + core::ops::BitOr<Self, Output = Self>
698    + core::ops::BitOr<Self::Integer, Output = Self>
699    + core::ops::BitOrAssign<Self>
700    + core::ops::BitOrAssign<Self::Integer>
701    + core::panic::RefUnwindSafe
702    + core::panic::UnwindSafe
703    + core::str::FromStr<Err = ParseIntError>
704{
705    /// The primitive integer type that this non-zero type wraps.
706    ///
707    /// For `core::num::NonZero<T>`, this is `T`.
708    type Integer: PrimitiveInteger<NonZero = Self>;
709
710    /// The size of this non-zero integer type in bits.
711    const BITS: u32;
712
713    /// The largest value that can be represented by this non-zero integer type.
714    const MAX: Self;
715
716    /// The smallest value that can be represented by this non-zero integer type.
717    const MIN: Self;
718
719    /// Multiplies two non-zero integers together. Returns [`None`] on overflow.
720    fn checked_mul(self, other: Self) -> Option<Self>;
721
722    /// Raises non-zero value to an integer power. Returns [`None`] on overflow.
723    fn checked_pow(self, other: u32) -> Option<Self>;
724
725    /// Returns the number of ones in the binary representation of `self`.
726    fn count_ones(self) -> NonZero<u32>;
727
728    /// Parses a non-zero integer from a string slice with digits in a given base.
729    fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
730
731    /// Returns the contained value as a primitive type.
732    fn get(self) -> Self::Integer;
733
734    /// Returns the index of the highest bit set to one in `self`.
735    fn highest_one(self) -> u32;
736
737    /// Returns `self` with only the most significant bit set.
738    fn isolate_highest_one(self) -> Self;
739
740    /// Returns `self` with only the least significant bit set.
741    fn isolate_lowest_one(self) -> Self;
742
743    /// Returns the number of leading zeros in the binary representation of `self`.
744    fn leading_zeros(self) -> u32;
745
746    /// Returns the index of the lowest bit set to one in `self`.
747    fn lowest_one(self) -> u32;
748
749    /// Creates a non-zero if the given value is not zero.
750    fn new(n: Self::Integer) -> Option<Self>;
751
752    /// Multiplies two non-zero integers together, saturating at the numeric bounds
753    /// instead of overflowing.
754    fn saturating_mul(self, other: Self) -> Self;
755
756    /// Raise non-zero value to an integer power, saturating at the numeric bounds
757    /// instead of overflowing.
758    fn saturating_pow(self, other: u32) -> Self;
759
760    /// Returns the number of trailing zeros in the binary representation of `self`.
761    fn trailing_zeros(self) -> u32;
762
763    /// Creates a non-zero without checking whether the value is non-zero.
764    /// This results in undefined behavior if the value is zero.
765    ///
766    /// # Safety
767    ///
768    /// The value must not be zero.
769    unsafe fn new_unchecked(n: Self::Integer) -> Self;
770}
771
772/// Trait for [`NumBuffer<T>`] for the decimal formatting of a primitive integer type.
773///
774/// In particular, this is used as a bound for the associated type [`PrimitiveInteger::NumBuffer`],
775/// passed as an argument to the [`format_into`][`PrimitiveInteger::format_into`] method. The main
776/// use for this trait is just to create a buffer with [`new`][Self::new].
777///
778/// This trait is sealed with a private trait to prevent downstream implementations, so we may
779/// continue to expand along with the standard library without worrying about breaking changes for
780/// implementors.
781///
782/// # Examples
783///
784/// ```
785/// use num_primitive::{PrimitiveInteger, PrimitiveNumBuffer};
786///
787/// fn check_format_into<T: PrimitiveInteger>(x: T) {
788///     assert!(size_of::<T::NumBuffer>() > size_of::<T>());
789///
790///     let mut buf = T::NumBuffer::new();
791///     assert_eq!(x.format_into(&mut buf), x.to_string());
792///
793///     // Note that the buffer can be reused for multiple calls.
794///     assert_eq!(T::default().format_into(&mut buf), "0");
795///     assert_eq!(T::as_from(1).format_into(&mut buf), "1");
796///     assert_eq!(T::MIN.format_into(&mut buf), T::MIN.to_string());
797///     assert_eq!(T::MAX.format_into(&mut buf), T::MAX.to_string());
798/// }
799///
800/// check_format_into(123_u64);
801/// check_format_into(-42_i32);
802///
803/// assert!(size_of::<<u64 as PrimitiveInteger>::NumBuffer>()
804///       > size_of::<<i32 as PrimitiveInteger>::NumBuffer>());
805/// ```
806#[expect(private_bounds)]
807pub trait PrimitiveNumBuffer:
808    'static
809    + Sealed
810    + core::fmt::Debug
811    + core::marker::Send
812    + core::marker::Sized
813    + core::marker::Sync
814    + core::marker::Unpin
815    + core::panic::RefUnwindSafe
816    + core::panic::UnwindSafe
817{
818    /// Creates a buffer.
819    fn new() -> Self;
820}
821
822macro_rules! impl_integer {
823    ($($Integer:ident),*) => {$(
824        impl PrimitiveInteger for $Integer {
825            type NonZero = NonZero<Self>;
826            type NumBuffer = NumBuffer<Self>;
827
828            use_consts!(Self::{
829                BITS: u32,
830                MAX: Self,
831                MIN: Self,
832            });
833
834            forward! {
835                fn from_be(value: Self) -> Self;
836                fn from_le(value: Self) -> Self;
837                fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
838            }
839            forward! {
840                fn checked_add(self, rhs: Self) -> Option<Self>;
841                fn checked_div(self, rhs: Self) -> Option<Self>;
842                fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
843                fn checked_ilog(self, base: Self) -> Option<u32>;
844                fn checked_ilog10(self) -> Option<u32>;
845                fn checked_ilog2(self) -> Option<u32>;
846                fn checked_mul(self, rhs: Self) -> Option<Self>;
847                fn checked_neg(self) -> Option<Self>;
848                fn checked_pow(self, exp: u32) -> Option<Self>;
849                fn checked_rem(self, rhs: Self) -> Option<Self>;
850                fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
851                fn checked_shl(self, rhs: u32) -> Option<Self>;
852                fn checked_shr(self, rhs: u32) -> Option<Self>;
853                fn checked_sub(self, rhs: Self) -> Option<Self>;
854                fn count_ones(self) -> u32;
855                fn count_zeros(self) -> u32;
856                fn div_euclid(self, rhs: Self) -> Self;
857                fn format_into(self, buf: &mut Self::NumBuffer) -> &str;
858                fn highest_one(self) -> Option<u32>;
859                fn ilog(self, base: Self) -> u32;
860                fn ilog10(self) -> u32;
861                fn ilog2(self) -> u32;
862                fn isolate_highest_one(self) -> Self;
863                fn isolate_lowest_one(self) -> Self;
864                fn isqrt(self) -> Self;
865                fn leading_ones(self) -> u32;
866                fn leading_zeros(self) -> u32;
867                fn lowest_one(self) -> Option<u32>;
868                fn overflowing_add(self, rhs: Self) -> (Self, bool);
869                fn overflowing_div(self, rhs: Self) -> (Self, bool);
870                fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
871                fn overflowing_mul(self, rhs: Self) -> (Self, bool);
872                fn overflowing_neg(self) -> (Self, bool);
873                fn overflowing_pow(self, exp: u32) -> (Self, bool);
874                fn overflowing_rem(self, rhs: Self) -> (Self, bool);
875                fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool);
876                fn overflowing_shl(self, rhs: u32) -> (Self, bool);
877                fn overflowing_shr(self, rhs: u32) -> (Self, bool);
878                fn overflowing_sub(self, rhs: Self) -> (Self, bool);
879                fn pow(self, exp: u32) -> Self;
880                fn rem_euclid(self, rhs: Self) -> Self;
881                fn reverse_bits(self) -> Self;
882                fn rotate_left(self, n: u32) -> Self;
883                fn rotate_right(self, n: u32) -> Self;
884                fn saturating_add(self, rhs: Self) -> Self;
885                fn saturating_div(self, rhs: Self) -> Self;
886                fn saturating_mul(self, rhs: Self) -> Self;
887                fn saturating_pow(self, exp: u32) -> Self;
888                fn saturating_sub(self, rhs: Self) -> Self;
889                fn strict_add(self, rhs: Self) -> Self;
890                fn strict_div(self, rhs: Self) -> Self;
891                fn strict_div_euclid(self, rhs: Self) -> Self;
892                fn strict_mul(self, rhs: Self) -> Self;
893                fn strict_neg(self) -> Self;
894                fn strict_pow(self, exp: u32) -> Self;
895                fn strict_rem(self, rhs: Self) -> Self;
896                fn strict_rem_euclid(self, rhs: Self) -> Self;
897                fn strict_shl(self, rhs: u32) -> Self;
898                fn strict_shr(self, rhs: u32) -> Self;
899                fn strict_sub(self, rhs: Self) -> Self;
900                fn swap_bytes(self) -> Self;
901                fn to_be(self) -> Self;
902                fn to_le(self) -> Self;
903                fn trailing_ones(self) -> u32;
904                fn trailing_zeros(self) -> u32;
905                fn unbounded_shl(self, rhs: u32) -> Self;
906                fn unbounded_shr(self, rhs: u32) -> Self;
907                fn wrapping_add(self, rhs: Self) -> Self;
908                fn wrapping_div(self, rhs: Self) -> Self;
909                fn wrapping_div_euclid(self, rhs: Self) -> Self;
910                fn wrapping_mul(self, rhs: Self) -> Self;
911                fn wrapping_neg(self) -> Self;
912                fn wrapping_pow(self, exp: u32) -> Self;
913                fn wrapping_rem(self, rhs: Self) -> Self;
914                fn wrapping_rem_euclid(self, rhs: Self) -> Self;
915                fn wrapping_shl(self, rhs: u32) -> Self;
916                fn wrapping_shr(self, rhs: u32) -> Self;
917                fn wrapping_sub(self, rhs: Self) -> Self;
918            }
919            forward! {
920                unsafe fn unchecked_add(self, rhs: Self) -> Self;
921                unsafe fn unchecked_mul(self, rhs: Self) -> Self;
922                unsafe fn unchecked_shl(self, rhs: u32) -> Self;
923                unsafe fn unchecked_shr(self, rhs: u32) -> Self;
924                unsafe fn unchecked_sub(self, rhs: Self) -> Self;
925            }
926        }
927
928        impl PrimitiveIntegerRef<$Integer> for &$Integer {}
929
930        impl Sealed for NonZero<$Integer> {}
931
932        impl NonZeroPrimitiveInteger for NonZero<$Integer> {
933            type Integer = $Integer;
934
935            use_consts!(Self::{
936                BITS: u32,
937                MAX: Self,
938                MIN: Self,
939            });
940
941            forward! {
942                fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
943                fn new(n: Self::Integer) -> Option<Self>;
944            }
945            forward! {
946                fn checked_mul(self, other: Self) -> Option<Self>;
947                fn checked_pow(self, other: u32) -> Option<Self>;
948                fn count_ones(self) -> NonZero<u32>;
949                fn get(self) -> Self::Integer;
950                fn highest_one(self) -> u32;
951                fn isolate_highest_one(self) -> Self;
952                fn isolate_lowest_one(self) -> Self;
953                fn leading_zeros(self) -> u32;
954                fn lowest_one(self) -> u32;
955                fn saturating_mul(self, other: Self) -> Self;
956                fn saturating_pow(self, other: u32) -> Self;
957                fn trailing_zeros(self) -> u32;
958            }
959            forward! {
960                unsafe fn new_unchecked(n: Self::Integer) -> Self;
961            }
962        }
963
964        impl Sealed for NumBuffer<$Integer> {}
965
966        impl PrimitiveNumBuffer for NumBuffer<$Integer> {
967            forward! {
968                fn new() -> Self;
969            }
970        }
971    )*}
972}
973
974impl_integer!(i8, i16, i32, i64, i128, isize);
975impl_integer!(u8, u16, u32, u64, u128, usize);