num_primitive/
unsigned.rs

1use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveSigned};
2
3/// Trait for all primitive [unsigned integer types], including the supertraits
4/// [`PrimitiveInteger`] and [`PrimitiveNumber`][crate::PrimitiveNumber].
5///
6/// This encapsulates trait implementations and inherent methods that are common among all of the
7/// primitive unsigned integer types: [`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/// [unsigned integer types]: https://doc.rust-lang.org/reference/types/numeric.html#r-type.numeric.int.unsigned
16///
17/// # Examples
18///
19/// ```
20/// use num_primitive::PrimitiveUnsigned;
21///
22/// // Greatest Common Divisor (Euclidean algorithm)
23/// fn gcd<T: PrimitiveUnsigned>(mut a: T, mut b: T) -> T {
24///     let zero = T::from(0u8);
25///     while b != zero {
26///         (a, b) = (b, a % b);
27///     }
28///     a
29/// }
30///
31/// assert_eq!(gcd::<u8>(48, 18), 6);
32/// assert_eq!(gcd::<u16>(1071, 462), 21);
33/// assert_eq!(gcd::<u32>(6_700_417, 2_147_483_647), 1);
34/// ```
35pub trait PrimitiveUnsigned: PrimitiveInteger + From<u8> {
36    /// The signed integer type used by methods like
37    /// [`checked_add_signed`][Self::checked_add_signed].
38    type Signed: PrimitiveSigned;
39
40    /// Computes the absolute difference between `self` and `other`.
41    fn abs_diff(self, other: Self) -> Self;
42
43    /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
44    fn cast_signed(self) -> Self::Signed;
45
46    /// Checked addition with a signed integer. Computes `self + rhs`, returning `None` if overflow
47    /// occurred.
48    fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
49
50    /// Calculates the smallest value greater than or equal to `self` that is a multiple of `rhs`.
51    /// Returns `None` if `rhs` is zero or the operation would result in overflow.
52    fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
53
54    /// Returns the smallest power of two greater than or equal to `self`. If the next power of two
55    /// is greater than the type's maximum value, `None` is returned, otherwise the power of two is
56    /// wrapped in Some.
57    fn checked_next_power_of_two(self) -> Option<Self>;
58
59    /// Checked subtraction with a signed integer. Computes `self - rhs`,
60    /// returning `None` if overflow occurred.
61    fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
62
63    /// Calculates the quotient of `self` and rhs, rounding the result towards positive infinity.
64    fn div_ceil(self, rhs: Self) -> Self;
65
66    /// Returns `true` if `self` is an integer multiple of `rhs`, and false otherwise.
67    fn is_multiple_of(self, rhs: Self) -> bool;
68
69    /// Returns `true` if and only if `self == 2^k` for some `k`.
70    fn is_power_of_two(self) -> bool;
71
72    /// Calculates the smallest value greater than or equal to `self` that is a multiple of `rhs`.
73    fn next_multiple_of(self, rhs: Self) -> Self;
74
75    /// Returns the smallest power of two greater than or equal to `self`.
76    fn next_power_of_two(self) -> Self;
77
78    /// Calculates `self + rhs` with a signed `rhs`. Returns a tuple of the addition along with a
79    /// boolean indicating whether an arithmetic overflow would occur.
80    fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
81
82    /// Calculates `self` - `rhs` with a signed `rhs`. Returns a tuple of the subtraction along
83    /// with a boolean indicating whether an arithmetic overflow would occur.
84    fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
85
86    /// Saturating addition with a signed integer. Computes `self + rhs`, saturating at the numeric
87    /// bounds instead of overflowing.
88    fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
89
90    /// Saturating integer subtraction. Computes `self` - `rhs`, saturating at
91    /// the numeric bounds instead of overflowing.
92    fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
93
94    /// Wrapping (modular) addition with a signed integer. Computes `self + rhs`, wrapping around
95    /// at the boundary of the type.
96    fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
97
98    /// Wrapping (modular) subtraction with a signed integer. Computes
99    /// `self - rhs`, wrapping around at the boundary of the type.
100    fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
101}
102
103/// Trait for references to primitive unsigned integer types ([`PrimitiveUnsigned`]).
104///
105/// This enables traits like the standard operators in generic code,
106/// e.g. `where &T: PrimitiveUnsignedRef<T>`.
107pub trait PrimitiveUnsignedRef<T>: PrimitiveIntegerRef<T> {}
108
109macro_rules! impl_unsigned {
110    ($Unsigned:ident, $Signed:ty) => {
111        impl PrimitiveUnsigned for $Unsigned {
112            type Signed = $Signed;
113
114            forward! {
115                fn abs_diff(self, other: Self) -> Self;
116                fn cast_signed(self) -> Self::Signed;
117                fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
118                fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
119                fn checked_next_power_of_two(self) -> Option<Self>;
120                fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
121                fn div_ceil(self, rhs: Self) -> Self;
122                fn is_multiple_of(self, rhs: Self) -> bool;
123                fn is_power_of_two(self) -> bool;
124                fn next_multiple_of(self, rhs: Self) -> Self;
125                fn next_power_of_two(self) -> Self;
126                fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
127                fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
128                fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
129                fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
130                fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
131                fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
132            }
133        }
134
135        impl PrimitiveUnsignedRef<$Unsigned> for &$Unsigned {}
136    };
137}
138
139impl_unsigned!(u8, i8);
140impl_unsigned!(u16, i16);
141impl_unsigned!(u32, i32);
142impl_unsigned!(u64, i64);
143impl_unsigned!(u128, i128);
144impl_unsigned!(usize, isize);