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` − `rhs` − `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);