Skip to main content

num_primitive/
unsigned.rs

1use core::convert::Infallible;
2use core::num::NonZero;
3
4use crate::{
5    NonZeroPrimitiveInteger, NonZeroPrimitiveSigned, PrimitiveInteger, PrimitiveIntegerRef,
6    PrimitiveSigned,
7};
8
9/// Trait for all primitive [unsigned integer types], including the supertraits
10/// [`PrimitiveInteger`] and [`PrimitiveNumber`][crate::PrimitiveNumber].
11///
12/// This encapsulates trait implementations and inherent methods that are common among all of the
13/// primitive unsigned integer types: [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], and [`usize`].
14///
15/// See the corresponding items on the individual types for more documentation and examples.
16///
17/// This trait is sealed with a private trait to prevent downstream implementations, so we may
18/// continue to expand along with the standard library without worrying about breaking changes for
19/// implementors.
20///
21/// [unsigned integer types]: https://doc.rust-lang.org/reference/types/numeric.html#r-type.numeric.int.unsigned
22///
23/// # Examples
24///
25/// ```
26/// use num_primitive::PrimitiveUnsigned;
27///
28/// // Greatest Common Divisor (Euclidean algorithm)
29/// fn gcd<T: PrimitiveUnsigned>(mut a: T, mut b: T) -> T {
30///     let zero = T::from(0u8);
31///     while b != zero {
32///         (a, b) = (b, a % b);
33///     }
34///     a
35/// }
36///
37/// assert_eq!(gcd::<u8>(48, 18), 6);
38/// assert_eq!(gcd::<u16>(1071, 462), 21);
39/// assert_eq!(gcd::<u32>(6_700_417, 2_147_483_647), 1);
40/// ```
41pub trait PrimitiveUnsigned:
42    PrimitiveInteger
43    + core::convert::From<u8>
44    + core::convert::TryFrom<u8, Error = Infallible>
45    + core::ops::Div<Self::NonZero, Output = Self>
46    + core::ops::DivAssign<Self::NonZero>
47    + core::ops::Rem<Self::NonZero, Output = Self>
48    + core::ops::RemAssign<Self::NonZero>
49{
50    /// The signed integer type used by methods like
51    /// [`checked_add_signed`][Self::checked_add_signed].
52    type Signed: PrimitiveSigned;
53
54    /// Computes the absolute difference between `self` and `other`.
55    fn abs_diff(self, other: Self) -> Self;
56
57    /// Calculates `self` &minus; `rhs` &minus; `borrow` and returns a tuple
58    /// containing the difference and the output borrow.
59    fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
60
61    /// Calculates `self` + `rhs` + `carry` and returns a tuple containing
62    /// the sum and the output carry (in that order).
63    fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
64
65    /// Calculates the "full multiplication" `self * rhs + carry`
66    /// without the possibility to overflow.
67    fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
68
69    /// Calculates the "full multiplication" `self * rhs + carry + add`.
70    fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self);
71
72    /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
73    fn cast_signed(self) -> Self::Signed;
74
75    /// Checked addition with a signed integer. Computes `self + rhs`, returning `None` if overflow
76    /// occurred.
77    fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
78
79    /// Calculates the smallest value greater than or equal to `self` that is a multiple of `rhs`.
80    /// Returns `None` if `rhs` is zero or the operation would result in overflow.
81    fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
82
83    /// Returns the smallest power of two greater than or equal to `self`. If the next power of two
84    /// is greater than the type's maximum value, `None` is returned, otherwise the power of two is
85    /// wrapped in Some.
86    fn checked_next_power_of_two(self) -> Option<Self>;
87
88    /// Checked integer subtraction. Computes `self - rhs` and checks if the result fits into a
89    /// signed integer of the same size, returning `None` if overflow occurred.
90    fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;
91
92    /// Checked subtraction with a signed integer. Computes `self - rhs`,
93    /// returning `None` if overflow occurred.
94    fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
95
96    /// Calculates the quotient of `self` and rhs, rounding the result towards positive infinity.
97    fn div_ceil(self, rhs: Self) -> Self;
98
99    /// Returns `true` if `self` is an integer multiple of `rhs`, and false otherwise.
100    fn is_multiple_of(self, rhs: Self) -> bool;
101
102    /// Returns `true` if and only if `self == 2^k` for some `k`.
103    fn is_power_of_two(self) -> bool;
104
105    /// Calculates the smallest value greater than or equal to `self` that is a multiple of `rhs`.
106    fn next_multiple_of(self, rhs: Self) -> Self;
107
108    /// Returns the smallest power of two greater than or equal to `self`.
109    fn next_power_of_two(self) -> Self;
110
111    /// Calculates `self + rhs` with a signed `rhs`. Returns a tuple of the addition along with a
112    /// boolean indicating whether an arithmetic overflow would occur.
113    fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
114
115    /// Calculates `self` - `rhs` with a signed `rhs`. Returns a tuple of the subtraction along
116    /// with a boolean indicating whether an arithmetic overflow would occur.
117    fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
118
119    /// Saturating addition with a signed integer. Computes `self + rhs`, saturating at the numeric
120    /// bounds instead of overflowing.
121    fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
122
123    /// Saturating integer subtraction. Computes `self` - `rhs`, saturating at
124    /// the numeric bounds instead of overflowing.
125    fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
126
127    /// Strict addition with a signed integer. Computes `self + rhs`,
128    /// panicking if overflow occurred.
129    fn strict_add_signed(self, rhs: Self::Signed) -> Self;
130
131    /// Strict subtraction with a signed integer. Computes `self - rhs`,
132    /// panicking if overflow occurred.
133    fn strict_sub_signed(self, rhs: Self::Signed) -> Self;
134
135    /// Wrapping (modular) addition with a signed integer. Computes `self + rhs`, wrapping around
136    /// at the boundary of the type.
137    fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
138
139    /// Wrapping (modular) subtraction with a signed integer. Computes
140    /// `self - rhs`, wrapping around at the boundary of the type.
141    fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
142}
143
144/// Trait for references to primitive unsigned integer types ([`PrimitiveUnsigned`]).
145///
146/// This enables traits like the standard operators in generic code,
147/// e.g. `where &T: PrimitiveUnsignedRef<T>`.
148pub trait PrimitiveUnsignedRef<T>: PrimitiveIntegerRef<T> {}
149
150/// Trait for [`NonZero`] primitive unsigned integers, including the supertrait
151/// [`NonZeroPrimitiveInteger`].
152///
153/// This encapsulates trait implementations and inherent methods that are common among all of the
154/// implementations of `NonZero<T>`, where `T` is a [`PrimitiveUnsigned`].
155///
156/// See the corresponding items on the individual types for more documentation and examples.
157///
158/// This trait is sealed with a private trait to prevent downstream implementations, so we may
159/// continue to expand along with the standard library without worrying about breaking changes for
160/// implementors.
161///
162/// # Examples
163///
164/// ```
165/// use num_primitive::NonZeroPrimitiveUnsigned;
166/// use core::num::NonZero;
167///
168/// fn gcd<T: NonZeroPrimitiveUnsigned>(mut a: T, mut b: T) -> T {
169///     while let Some(r) = T::new(b.get() % a) {
170///         (a, b) = (r, a);
171///     }
172///     a
173/// }
174///
175/// let a = NonZero::new(48u32).unwrap();
176/// let b = NonZero::new(18u32).unwrap();
177/// assert_eq!(gcd(a, b).get(), 6);
178/// ```
179pub trait NonZeroPrimitiveUnsigned:
180    NonZeroPrimitiveInteger<Integer: PrimitiveUnsigned> + core::convert::From<NonZero<u8>>
181{
182    /// The signed non-zero integer type used by methods like
183    /// [`cast_signed`][Self::cast_signed].
184    ///
185    /// For `core::num::NonZero<T>`, this is `NonZero<T::Signed>`.
186    type NonZeroSigned: NonZeroPrimitiveSigned;
187
188    /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
189    fn cast_signed(self) -> Self::NonZeroSigned;
190
191    /// Adds an unsigned integer to a non-zero value. Returns [`None`] on overflow.
192    fn checked_add(self, other: Self::Integer) -> Option<Self>;
193
194    /// Returns the smallest power of two greater than or equal to `self`. Checks for overflow and
195    /// returns [`None`] if the next power of two is greater than the type’s maximum value.
196    fn checked_next_power_of_two(self) -> Option<Self>;
197
198    /// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity.
199    fn div_ceil(self, rhs: Self) -> Self;
200
201    /// Returns the base 10 logarithm of the number, rounded down.
202    fn ilog10(self) -> u32;
203
204    /// Returns the base 2 logarithm of the number, rounded down.
205    fn ilog2(self) -> u32;
206
207    /// Returns `true` if and only if `self == (1 << k)` for some `k`.
208    fn is_power_of_two(self) -> bool;
209
210    /// Returns the square root of the number, rounded down.
211    fn isqrt(self) -> Self;
212
213    /// Calculates the midpoint (average) between `self` and `rhs`.
214    fn midpoint(self, rhs: Self) -> Self;
215
216    /// Adds an unsigned integer to a non-zero value. Returns `Self::MAX` on overflow.
217    fn saturating_add(self, other: Self::Integer) -> Self;
218}
219
220macro_rules! impl_unsigned {
221    ($Unsigned:ident, $Signed:ty) => {
222        impl PrimitiveUnsigned for $Unsigned {
223            type Signed = $Signed;
224
225            forward! {
226                fn abs_diff(self, other: Self) -> Self;
227                fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
228                fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
229                fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
230                fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self);
231                fn cast_signed(self) -> Self::Signed;
232                fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
233                fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
234                fn checked_next_power_of_two(self) -> Option<Self>;
235                fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;
236                fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
237                fn div_ceil(self, rhs: Self) -> Self;
238                fn is_multiple_of(self, rhs: Self) -> bool;
239                fn is_power_of_two(self) -> bool;
240                fn next_multiple_of(self, rhs: Self) -> Self;
241                fn next_power_of_two(self) -> Self;
242                fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
243                fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
244                fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
245                fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
246                fn strict_add_signed(self, rhs: Self::Signed) -> Self;
247                fn strict_sub_signed(self, rhs: Self::Signed) -> Self;
248                fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
249                fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
250            }
251        }
252
253        impl PrimitiveUnsignedRef<$Unsigned> for &$Unsigned {}
254
255        impl NonZeroPrimitiveUnsigned for NonZero<$Unsigned> {
256            type NonZeroSigned = NonZero<$Signed>;
257
258            forward! {
259                fn cast_signed(self) -> Self::NonZeroSigned;
260                fn checked_add(self, other: Self::Integer) -> Option<Self>;
261                fn checked_next_power_of_two(self) -> Option<Self>;
262                fn div_ceil(self, rhs: Self) -> Self;
263                fn ilog10(self) -> u32;
264                fn ilog2(self) -> u32;
265                fn is_power_of_two(self) -> bool;
266                fn isqrt(self) -> Self;
267                fn midpoint(self, rhs: Self) -> Self;
268                fn saturating_add(self, other: Self::Integer) -> Self;
269            }
270        }
271    };
272}
273
274impl_unsigned!(u8, i8);
275impl_unsigned!(u16, i16);
276impl_unsigned!(u32, i32);
277impl_unsigned!(u64, i64);
278impl_unsigned!(u128, i128);
279impl_unsigned!(usize, isize);