arbitrary_int/
unsigned.rs

1use crate::common::{
2    bytes_operation_impl, from_arbitrary_int_impl, from_native_impl, impl_borsh, impl_extract,
3    impl_num_traits, impl_schemars, impl_step, impl_sum_product,
4};
5use crate::traits::{sealed::Sealed, BuiltinInteger, Integer, UnsignedInteger};
6use crate::TryNewError;
7use core::fmt::{Binary, Debug, Display, Formatter, LowerHex, Octal, UpperHex};
8use core::ops::{
9    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
10    Mul, MulAssign, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
11};
12
13macro_rules! impl_integer_native {
14    // `$const_keyword` is marked as an optional fragment here so that it can conditionally be put on the impl.
15    // This macro will be invoked with `(u8,i8) as const, ...` if `const_convert_and_const_trait_impl` is enabled.
16    ($(($type:ident, $signed_type:ident) $(as $const_keyword:ident)?),+) => {
17        $(
18            #[allow(deprecated)]
19            impl crate::v1_number_compat::Number for $type {
20                type UnderlyingType = $type;
21            }
22
23            impl $($const_keyword)? Sealed for $type {}
24
25            impl $($const_keyword)? BuiltinInteger for $type {}
26
27            impl $($const_keyword)? UnsignedInteger for $type {}
28
29            impl $($const_keyword)? Integer for $type {
30                type UnderlyingType = $type;
31                type UnsignedInteger = $type;
32                type SignedInteger = $signed_type;
33
34                const BITS: usize = Self::BITS as usize;
35                const ZERO: Self = 0;
36                const MIN: Self = Self::MIN;
37                const MAX: Self = Self::MAX;
38
39                #[inline]
40                fn new(value: Self::UnderlyingType) -> Self { value }
41
42                #[inline]
43                fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> { Ok(value) }
44
45                #[inline]
46                fn value(self) -> Self::UnderlyingType { self }
47
48                #[cfg(not(feature = "const_convert_and_const_trait_impl"))]
49                #[inline]
50                fn from_<T: $(~ $const_keyword)? Integer>(value: T) -> Self {
51                    if T::BITS > Self::BITS as usize {
52                        assert!(value <= T::masked_new(Self::MAX));
53                    }
54                    Self::masked_new(value)
55                }
56
57                #[inline]
58                fn masked_new<T: $(~ $const_keyword)? Integer>(value: T) -> Self {
59                    // Primitive types don't need masking
60                    match Self::BITS {
61                        8 => value.as_u8() as Self,
62                        16 => value.as_u16() as Self,
63                        32 => value.as_u32() as Self,
64                        64 => value.as_u64() as Self,
65                        128 => value.as_u128() as Self,
66                        _ => panic!("Unhandled Integer type")
67                    }
68                }
69
70                #[inline]
71                fn as_u8(self) -> u8 { self as u8 }
72
73                #[inline]
74                fn as_u16(self) -> u16 { self as u16 }
75
76                #[inline]
77                fn as_u32(self) -> u32 { self as u32 }
78
79                #[inline]
80                fn as_u64(self) -> u64 { self as u64 }
81
82                #[inline]
83                fn as_u128(self) -> u128 { self as u128 }
84
85                #[inline]
86                fn as_usize(self) -> usize { self as usize }
87
88                #[inline]
89                fn as_i8(self) -> i8 { self as i8 }
90
91                #[inline]
92                fn as_i16(self) -> i16 { self as i16 }
93
94                #[inline]
95                fn as_i32(self) -> i32 { self as i32 }
96
97                #[inline]
98                fn as_i64(self) -> i64 { self as i64 }
99
100                #[inline]
101                fn as_i128(self) -> i128 { self as i128 }
102
103                #[inline]
104                fn as_isize(self) -> isize { self as isize }
105
106                #[inline]
107                fn to_unsigned(self) -> Self::UnsignedInteger { self }
108
109                #[inline]
110                fn from_unsigned(value: Self::UnsignedInteger) -> Self { value }
111            }
112        )+
113    };
114}
115
116#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
117impl_integer_native!((u8, i8), (u16, i16), (u32, i32), (u64, i64), (u128, i128));
118
119#[cfg(feature = "const_convert_and_const_trait_impl")]
120impl_integer_native!((u8, i8) as const, (u16, i16) as const, (u32, i32) as const, (u64, i64) as const, (u128, i128) as const);
121
122#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
123pub struct UInt<T: UnsignedInteger + BuiltinInteger, const BITS: usize> {
124    value: T,
125}
126
127impl<T: UnsignedInteger + BuiltinInteger, const BITS: usize> UInt<T, BITS> {
128    /// The number of bits in the underlying type that are not present in this type.
129    const UNUSED_BITS: usize = (core::mem::size_of::<T>() << 3) - Self::BITS;
130
131    pub const BITS: usize = BITS;
132
133    /// Returns the type as a fundamental data type
134    #[cfg(not(feature = "hint"))]
135    #[inline]
136    pub const fn value(self) -> T {
137        self.value
138    }
139
140    /// Initializes a new value without checking the bounds
141    ///
142    /// # Safety
143    /// Must only be called with a value less than or equal to [Self::MAX](Self::MAX) value.
144    #[inline]
145    pub const unsafe fn new_unchecked(value: T) -> Self {
146        Self { value }
147    }
148}
149
150impl<T: UnsignedInteger + BuiltinInteger, const BITS: usize> UInt<T, BITS>
151where
152    Self: Integer,
153    T: Copy,
154{
155    pub const MASK: T = Self::MAX.value;
156}
157
158// Next are specific implementations for u8, u16, u32, u64 and u128. A couple notes:
159// - The existence of MAX also serves as a neat bounds-check for BITS: If BITS is too large,
160//   the subtraction overflows which will fail to compile. This simplifies things a lot.
161//   However, that only works if every constructor also uses MAX somehow (doing let _ = MAX is enough)
162
163macro_rules! uint_impl_num {
164    // `$const_keyword` is marked as an optional fragment here so that it can conditionally be put on the impl.
165    // This macro will be invoked with `(u8, i8) as const, ...` if `const_convert_and_const_trait_impl` is enabled.
166    ($(($type:ident, $signed_type:ident) $(as $const_keyword:ident)?),+) => {
167        $(
168            #[allow(deprecated)]
169            impl<const BITS: usize> crate::v1_number_compat::Number for UInt<$type, BITS> {
170                type UnderlyingType = $type;
171            }
172
173            impl<const BITS: usize> $($const_keyword)? Sealed for UInt<$type, BITS> {}
174
175            impl<const BITS: usize> $($const_keyword)? UnsignedInteger for UInt<$type, BITS> {}
176
177            impl<const BITS: usize> $($const_keyword)? Integer for UInt<$type, BITS> {
178                type UnderlyingType = $type;
179                type SignedInteger = crate::Int<$signed_type, BITS>;
180                type UnsignedInteger = Self;
181
182                const BITS: usize = BITS;
183
184                const ZERO: Self = Self { value: 0 };
185
186                const MIN: Self = Self { value: 0 };
187
188                // The existence of MAX also serves as a bounds check: If NUM_BITS is > available bits,
189                // we will get a compiler error right here
190                const MAX: Self = Self { value: (<$type as Integer>::MAX >> (<$type as Integer>::BITS - Self::BITS)) };
191
192                #[inline]
193                fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> {
194                    if value <= Self::MAX.value {
195                        Ok(Self { value })
196                    } else {
197                        Err(TryNewError{})
198                    }
199                }
200
201                #[inline]
202                fn new(value: $type) -> Self {
203                    assert!(value <= Self::MAX.value);
204
205                    Self { value }
206                }
207
208                #[cfg(not(feature = "const_convert_and_const_trait_impl"))]
209                #[inline]
210                fn from_<T: Integer>(value: T) -> Self {
211                    if Self::BITS < T::BITS {
212                        assert!(value <= Self::MAX.value.as_());
213                    }
214                    Self { value: Self::UnderlyingType::masked_new(value) }
215                }
216
217                fn masked_new<T: $(~ $const_keyword)? Integer>(value: T) -> Self {
218                    if Self::BITS < T::BITS {
219                        Self { value: Self::UnderlyingType::masked_new(value.as_::<Self::UnderlyingType>() & Self::MASK) }
220                    } else {
221                        Self { value: Self::UnderlyingType::masked_new(value) }
222                    }
223                }
224
225                fn as_u8(self) -> u8 {
226                    self.value() as _
227                }
228
229                fn as_u16(self) -> u16 {
230                    self.value() as _
231                }
232
233                fn as_u32(self) -> u32 {
234                    self.value() as _
235                }
236
237                fn as_u64(self) -> u64 {
238                    self.value() as _
239                }
240
241                fn as_u128(self) -> u128 {
242                    self.value() as _
243                }
244
245                fn as_usize(self) -> usize {
246                    self.value() as _
247                }
248
249                fn as_i8(self) -> i8 {
250                    self.value() as _
251                }
252
253                fn as_i16(self) -> i16 {
254                    self.value() as _
255                }
256
257                fn as_i32(self) -> i32 {
258                    self.value() as _
259                }
260
261                fn as_i64(self) -> i64 {
262                    self.value() as _
263                }
264
265                fn as_i128(self) -> i128 {
266                    self.value() as _
267                }
268
269                fn as_isize(self) -> isize {
270                    self.value() as _
271                }
272
273                #[inline]
274                fn to_unsigned(self) -> Self::UnsignedInteger { self }
275
276                #[inline]
277                fn from_unsigned(value: Self::UnsignedInteger) -> Self { value }
278
279                #[inline]
280                fn value(self) -> $type {
281                    #[cfg(feature = "hint")]
282                    unsafe {
283                        core::hint::assert_unchecked(self.value <= Self::MAX.value);
284                    }
285
286                    self.value
287                }
288            }
289        )+
290    };
291}
292
293#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
294uint_impl_num!((u8, i8), (u16, i16), (u32, i32), (u64, i64), (u128, i128));
295
296#[cfg(feature = "const_convert_and_const_trait_impl")]
297uint_impl_num!((u8, i8) as const, (u16, i16) as const, (u32, i32) as const, (u64, i64) as const, (u128, i128) as const);
298
299macro_rules! uint_impl {
300    ($(($type:ident, doctest = $doctest_attr:literal)),+) => {
301        $(
302            impl<const BITS: usize> UInt<$type, BITS> {
303                /// Creates an instance. Panics if the given value is outside of the valid range
304                #[inline]
305                pub const fn new(value: $type) -> Self {
306                    assert!(value <= Self::MAX.value);
307
308                    Self { value }
309                }
310
311                /// Creates an instance. Panics if the given value is outside of the valid range
312                #[inline]
313                pub const fn from_u8(value: u8) -> Self {
314                    if Self::BITS < 8 {
315                        assert!(value <= Self::MAX.value as u8);
316                    }
317                    Self { value: value as $type }
318                }
319
320                /// Creates an instance. Panics if the given value is outside of the valid range
321                #[inline]
322                pub const fn from_u16(value: u16) -> Self {
323                    if Self::BITS < 16 {
324                        assert!(value <= Self::MAX.value as u16);
325                    }
326                    Self { value: value as $type }
327                }
328
329                /// Creates an instance. Panics if the given value is outside of the valid range
330                #[inline]
331                pub const fn from_u32(value: u32) -> Self {
332                    if Self::BITS < 32 {
333                        assert!(value <= Self::MAX.value as u32);
334                    }
335                    Self { value: value as $type }
336                }
337
338                /// Creates an instance. Panics if the given value is outside of the valid range
339                #[inline]
340                pub const fn from_u64(value: u64) -> Self {
341                    if Self::BITS < 64 {
342                        assert!(value <= Self::MAX.value as u64);
343                    }
344                    Self { value: value as $type }
345                }
346
347                /// Creates an instance. Panics if the given value is outside of the valid range
348                #[inline]
349                pub const fn from_u128(value: u128) -> Self {
350                    if Self::BITS < 128 {
351                        assert!(value <= Self::MAX.value as u128);
352                    }
353                    Self { value: value as $type }
354                }
355
356                /// Creates an instance or an error if the given value is outside of the valid range
357                #[inline]
358                pub const fn try_new(value: $type) -> Result<Self, TryNewError> {
359                    if value <= Self::MAX.value {
360                        Ok(Self { value })
361                    } else {
362                        Err(TryNewError {})
363                    }
364                }
365
366                /// Returns the type as a fundamental data type
367                #[cfg(feature = "hint")]
368                #[inline]
369                pub const fn value(self) -> $type {
370                    // The hint feature requires the type to be const-comparable,
371                    // which isn't possible in the generic version above. So we have
372                    // an entirely different function if this feature is enabled.
373                    // It only works for primitive types, which should be ok in practice
374                    // (but is technically an API change)
375                    unsafe {
376                        core::hint::assert_unchecked(self.value <= Self::MAX.value);
377                    }
378                    self.value
379                }
380
381                #[deprecated(note = "Use one of the specific functions like extract_u32")]
382                pub const fn extract(value: $type, start_bit: usize) -> Self {
383                    assert!(start_bit + BITS <= $type::BITS as usize);
384                    // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
385                    let _ = Self::MAX;
386
387                    Self {
388                        value: (value >> start_bit) & Self::MAX.value,
389                    }
390                }
391
392                // Generate the `extract_{i,u}{8,16,32,64,128}` functions.
393                impl_extract!(
394                    $type,
395                    "new((value >> start_bit) & MASK)",
396                    |value| value & Self::MASK,
397
398                    (8, (u8, extract_u8), (i8, extract_i8)),
399                    (16, (u16, extract_u16), (i16, extract_i16)),
400                    (32, (u32, extract_u32), (i32, extract_i32)),
401                    (64, (u64, extract_u64), (i64, extract_i64)),
402                    (128, (u128, extract_u128), (i128, extract_i128))
403                );
404
405                /// Returns a [`UInt`] with a wider bit depth but with the same base data type
406                #[inline]
407                #[must_use = "this returns the result of the operation, without modifying the original"]
408                pub const fn widen<const BITS_RESULT: usize>(
409                    self,
410                ) -> UInt<$type, BITS_RESULT> {
411                    const { if BITS >= BITS_RESULT {
412                        panic!("Can not call widen() with the given bit widths");
413                    } };
414
415                    // Query MAX of the result to ensure we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
416                    let _ = UInt::<$type, BITS_RESULT>::MAX;
417                    UInt::<$type, BITS_RESULT> { value: self.value() }
418                }
419
420                /// Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the
421                /// boundary of the type.
422                ///
423                /// # Examples
424                ///
425                /// Basic usage:
426                ///
427                #[doc = concat!(" ```", $doctest_attr)]
428                /// # use arbitrary_int::prelude::*;
429                /// assert_eq!(u14::new(200).wrapping_add(u14::new(55)), u14::new(255));
430                /// assert_eq!(u14::new(200).wrapping_add(u14::MAX), u14::new(199));
431                /// ```
432                #[inline]
433                #[must_use = "this returns the result of the operation, without modifying the original"]
434                pub const fn wrapping_add(self, rhs: Self) -> Self {
435                    let sum = self.value().wrapping_add(rhs.value());
436                    Self {
437                        value: sum & Self::MASK,
438                    }
439                }
440
441                /// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
442                /// boundary of the type.
443                ///
444                /// # Examples
445                ///
446                /// Basic usage:
447                ///
448                #[doc = concat!(" ```", $doctest_attr)]
449                /// # use arbitrary_int::prelude::*;
450                /// assert_eq!(u14::new(100).wrapping_sub(u14::new(100)), u14::new(0));
451                /// assert_eq!(u14::new(100).wrapping_sub(u14::MAX), u14::new(101));
452                /// ```
453                #[inline]
454                #[must_use = "this returns the result of the operation, without modifying the original"]
455                pub const fn wrapping_sub(self, rhs: Self) -> Self {
456                    let sum = self.value().wrapping_sub(rhs.value());
457                    Self {
458                        value: sum & Self::MASK,
459                    }
460                }
461
462                /// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at the
463                /// boundary of the type.
464                ///
465                /// # Examples
466                ///
467                /// Basic usage:
468                ///
469                #[doc = concat!(" ```", $doctest_attr)]
470                /// # use arbitrary_int::u7;
471                /// assert_eq!(u7::new(10).wrapping_mul(u7::new(12)), u7::new(120));
472                /// assert_eq!(u7::new(25).wrapping_mul(u7::new(12)), u7::new(44));
473                /// ```
474                #[inline]
475                #[must_use = "this returns the result of the operation, without modifying the original"]
476                pub const fn wrapping_mul(self, rhs: Self) -> Self {
477                    let sum = self.value().wrapping_mul(rhs.value());
478                    Self {
479                        value: sum & Self::MASK,
480                    }
481                }
482
483                /// Wrapping (modular) division. Computes `self / rhs`.
484                ///
485                /// Wrapped division on unsigned types is just normal division. There’s no way
486                /// wrapping could ever happen. This function exists so that all operations are
487                /// accounted for in the wrapping operations.
488                ///
489                /// # Panics
490                ///
491                /// This function will panic if `rhs` is zero.
492                ///
493                /// # Examples
494                ///
495                /// Basic usage:
496                ///
497                #[doc = concat!(" ```", $doctest_attr)]
498                /// # use arbitrary_int::u14;
499                /// assert_eq!(u14::new(100).wrapping_div(u14::new(10)), u14::new(10));
500                /// ```
501                #[inline]
502                #[must_use = "this returns the result of the operation, without modifying the original"]
503                pub const fn wrapping_div(self, rhs: Self) -> Self {
504                    let sum = self.value().wrapping_div(rhs.value());
505                    Self {
506                        // No need to mask here - divisions always produce a result that is <= self
507                        value: sum,
508                    }
509                }
510
511                /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where mask
512                /// removes any high-order bits of `rhs` that would cause the shift to
513                /// exceed the bitwidth of the type.
514                ///
515                /// Note that this is not the same as a rotate-left; the RHS of a wrapping
516                /// shift-left is restricted to the range of the type, rather than the bits
517                /// shifted out of the LHS being returned to the other end.
518                /// A [`rotate_left`](Self::rotate_left) function exists as well, which may
519                /// be what you want instead.
520                ///
521                /// # Examples
522                ///
523                /// Basic usage:
524                ///
525                #[doc = concat!(" ```", $doctest_attr)]
526                /// # use arbitrary_int::u14;
527                /// assert_eq!(u14::new(1).wrapping_shl(7), u14::new(128));
528                /// assert_eq!(u14::new(1).wrapping_shl(128), u14::new(4));
529                /// ```
530                #[inline]
531                #[must_use = "this returns the result of the operation, without modifying the original"]
532                pub const fn wrapping_shl(self, rhs: u32) -> Self {
533                    // modulo is expensive on some platforms, so only do it when necessary
534                    let shift_amount = if rhs >= (BITS as u32) {
535                        rhs % (BITS as u32)
536                    } else {
537                        rhs
538                    };
539
540                    Self {
541                        // We could use wrapping_shl here to make Debug builds slightly smaller;
542                        // the downside would be that on weird CPUs that don't do wrapping_shl by
543                        // default release builds would get slightly worse. Using << should give
544                        // good release performance everywere
545                        value: (self.value() << shift_amount) & Self::MASK,
546                    }
547                }
548
549                /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where mask removes any
550                /// high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type.
551                ///
552                /// Note that this is not the same as a rotate-right; the RHS of a wrapping shift-right is
553                /// restricted to the range of the type, rather than the bits shifted out of the LHS being
554                /// returned to the other end.
555                /// A [`rotate_right`](Self::rotate_right) function exists as well, which may be what you
556                /// want instead.
557                ///
558                /// # Examples
559                ///
560                /// Basic usage:
561                ///
562                #[doc = concat!(" ```", $doctest_attr)]
563                /// # use arbitrary_int::u14;
564                /// assert_eq!(u14::new(128).wrapping_shr(7), u14::new(1));
565                /// assert_eq!(u14::new(128).wrapping_shr(128), u14::new(32));
566                /// ```
567                #[inline]
568                #[must_use = "this returns the result of the operation, without modifying the original"]
569                pub const fn wrapping_shr(self, rhs: u32) -> Self {
570                    // modulo is expensive on some platforms, so only do it when necessary
571                    let shift_amount = if rhs >= (BITS as u32) {
572                        rhs % (BITS as u32)
573                    } else {
574                        rhs
575                    };
576
577                    Self {
578                        value: (self.value() >> shift_amount),
579                    }
580                }
581
582                /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
583                /// bounds instead of overflowing.
584                ///
585                /// # Examples
586                ///
587                /// Basic usage:
588                ///
589                #[doc = concat!(" ```", $doctest_attr)]
590                /// # use arbitrary_int::prelude::*;
591                /// assert_eq!(u14::new(100).saturating_add(u14::new(1)), u14::new(101));
592                /// assert_eq!(u14::MAX.saturating_add(u14::new(100)), u14::MAX);
593                /// ```
594                #[inline]
595                #[must_use = "this returns the result of the operation, without modifying the original"]
596                pub const fn saturating_add(self, rhs: Self) -> Self {
597                    let saturated = if Self::UNUSED_BITS == 0 {
598                        // We are something like a UInt::<u8; 8>, we can fallback to the base implementation.
599                        // This is very unlikely to happen in practice, but checking allows us to use
600                        // `wrapping_add` instead of `saturating_add` in the common case, which is faster.
601                        self.value().saturating_add(rhs.value())
602                    } else {
603                        // We're dealing with fewer bits than the underlying type (e.g. u7).
604                        // That means the addition can never overflow the underlying type
605                        let sum = self.value().wrapping_add(rhs.value());
606                        let max = Self::MAX.value();
607                        if sum > max { max } else { sum }
608                    };
609                    Self {
610                        value: saturated,
611                    }
612                }
613
614                /// Saturating integer subtraction. Computes `self - rhs`, saturating at the numeric
615                /// bounds instead of overflowing.
616                ///
617                /// # Examples
618                ///
619                /// Basic usage:
620                ///
621                #[doc = concat!(" ```", $doctest_attr)]
622                /// # use arbitrary_int::u14;
623                /// assert_eq!(u14::new(100).saturating_sub(u14::new(27)), u14::new(73));
624                /// assert_eq!(u14::new(13).saturating_sub(u14::new(127)), u14::new(0));
625                /// ```
626                #[inline]
627                #[must_use = "this returns the result of the operation, without modifying the original"]
628                pub const fn saturating_sub(self, rhs: Self) -> Self {
629                    // For unsigned numbers, the only difference is when we reach 0 - which is the same
630                    // no matter the data size
631                    Self {
632                        value: self.value().saturating_sub(rhs.value()),
633                    }
634                }
635
636                /// Saturating integer multiplication. Computes `self * rhs`, saturating at the numeric
637                /// bounds instead of overflowing.
638                ///
639                /// # Examples
640                ///
641                /// Basic usage:
642                ///
643                #[doc = concat!(" ```", $doctest_attr)]
644                /// # use arbitrary_int::prelude::*;
645                /// assert_eq!(u14::new(2).saturating_mul(u14::new(10)), u14::new(20));
646                /// assert_eq!(u14::MAX.saturating_mul(u14::new(10)), u14::MAX);
647                /// ```
648                #[inline]
649                #[must_use = "this returns the result of the operation, without modifying the original"]
650                pub const fn saturating_mul(self, rhs: Self) -> Self {
651                    let product = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
652                        // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type
653                        // wrapping_mul likely provides the best performance on all cpus
654                        self.value().wrapping_mul(rhs.value())
655                    } else {
656                        // We have more than half the bits (e.g. u6 * u6)
657                        self.value().saturating_mul(rhs.value())
658                    };
659
660                    let max = Self::MAX.value();
661                    let saturated = if product > max { max } else { product };
662                    Self {
663                        value: saturated,
664                    }
665                }
666
667                /// Saturating integer division. Computes `self / rhs`, saturating at the numeric
668                /// bounds instead of overflowing.
669                ///
670                /// # Panics
671                ///
672                /// This function will panic if rhs is zero.
673                ///
674                /// # Examples
675                ///
676                /// Basic usage:
677                ///
678                #[doc = concat!(" ```", $doctest_attr)]
679                /// # use arbitrary_int::u14;
680                /// assert_eq!(u14::new(5).saturating_div(u14::new(2)), u14::new(2));
681                /// ```
682                #[inline]
683                #[must_use = "this returns the result of the operation, without modifying the original"]
684                pub const fn saturating_div(self, rhs: Self) -> Self {
685                    // When dividing unsigned numbers, we never need to saturate.
686                    // Division by zero in saturating_div throws an exception (in debug and release mode),
687                    // so no need to do anything special there either
688                    Self {
689                        value: self.value().saturating_div(rhs.value()),
690                    }
691                }
692
693                /// Saturating integer exponentiation. Computes `self.pow(exp)`, saturating at the numeric
694                /// bounds instead of overflowing.
695                ///
696                /// # Examples
697                ///
698                /// Basic usage:
699                ///
700                #[doc = concat!(" ```", $doctest_attr)]
701                /// # use arbitrary_int::prelude::*;
702                /// assert_eq!(u14::new(4).saturating_pow(3), u14::new(64));
703                /// assert_eq!(u14::MAX.saturating_pow(2), u14::MAX);
704                /// ```
705                #[inline]
706                #[must_use = "this returns the result of the operation, without modifying the original"]
707                pub const fn saturating_pow(self, exp: u32) -> Self {
708                    // It might be possible to handwrite this to be slightly faster as both
709                    // `saturating_pow` has to do a bounds-check and then we do second one.
710                    let powed = self.value().saturating_pow(exp);
711                    let max = Self::MAX.value();
712                    let saturated = if powed > max { max } else { powed };
713                    Self {
714                        value: saturated,
715                    }
716                }
717
718                /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
719                ///
720                /// # Examples
721                ///
722                /// Basic usage:
723                ///
724                #[doc = concat!(" ```", $doctest_attr)]
725                /// # use arbitrary_int::prelude::*;
726                /// assert_eq!((u14::MAX - u14::new(2)).checked_add(u14::new(1)), Some(u14::MAX - u14::new(1)));
727                /// assert_eq!((u14::MAX - u14::new(2)).checked_add(u14::new(3)), None);
728                /// ```
729                #[inline]
730                #[must_use = "this returns the result of the operation, without modifying the original"]
731                pub const fn checked_add(self, rhs: Self) -> Option<Self> {
732                    if Self::UNUSED_BITS == 0 {
733                        // We are something like a UInt::<u8; 8>, we can fallback to the base implementation.
734                        // This is very unlikely to happen in practice, but checking allows us to use
735                        // `wrapping_add` instead of `checked_add` in the common case, which is faster.
736                        match self.value().checked_add(rhs.value()) {
737                            Some(value) => Some(Self { value }),
738                            None => None
739                        }
740                    } else {
741                        // We're dealing with fewer bits than the underlying type (e.g. u7).
742                        // That means the addition can never overflow the underlying type
743                        let sum = self.value().wrapping_add(rhs.value());
744                        if sum > Self::MAX.value() { None } else { Some(Self { value: sum })}
745                    }
746                }
747
748                /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
749                ///
750                /// # Examples
751                ///
752                /// Basic usage:
753                ///
754                #[doc = concat!(" ```", $doctest_attr)]
755                /// # use arbitrary_int::u14;
756                /// assert_eq!(u14::new(1).checked_sub(u14::new(1)), Some(u14::new(0)));
757                /// assert_eq!(u14::new(0).checked_sub(u14::new(1)), None);
758                /// ```
759                #[inline]
760                #[must_use = "this returns the result of the operation, without modifying the original"]
761                pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
762                    match self.value().checked_sub(rhs.value()) {
763                        Some(value) => Some(Self { value }),
764                        None => None
765                    }
766                }
767
768                /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
769                ///
770                /// # Examples
771                ///
772                /// Basic usage:
773                ///
774                #[doc = concat!(" ```", $doctest_attr)]
775                /// # use arbitrary_int::prelude::*;
776                /// assert_eq!(u14::new(5).checked_mul(u14::new(1)), Some(u14::new(5)));
777                /// assert_eq!(u14::MAX.checked_mul(u14::new(2)), None);
778                /// ```
779                #[inline]
780                #[must_use = "this returns the result of the operation, without modifying the original"]
781                pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
782                    let product = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
783                        // We have half the bits (e.g. `u4 * u4`) of the base type, so we can't overflow the base type.
784                        // `wrapping_mul` likely provides the best performance on all CPUs.
785                        Some(self.value().wrapping_mul(rhs.value()))
786                    } else {
787                        // We have more than half the bits (e.g. u6 * u6)
788                        self.value().checked_mul(rhs.value())
789                    };
790
791                    match product {
792                        Some(value) if value <= Self::MAX.value() => Some(Self { value }),
793                        _ => None
794                    }
795                }
796
797                /// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`.
798                ///
799                /// # Examples
800                ///
801                /// Basic usage:
802                ///
803                #[doc = concat!(" ```", $doctest_attr)]
804                /// # use arbitrary_int::u14;
805                /// assert_eq!(u14::new(128).checked_div(u14::new(2)), Some(u14::new(64)));
806                /// assert_eq!(u14::new(1).checked_div(u14::new(0)), None);
807                /// ```
808                #[inline]
809                #[must_use = "this returns the result of the operation, without modifying the original"]
810                pub const fn checked_div(self, rhs: Self) -> Option<Self> {
811                    match self.value().checked_div(rhs.value()) {
812                        Some(value) => Some(Self { value }),
813                        None => None
814                    }
815                }
816
817                /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger than
818                /// or equal to the number of bits in `self`.
819                ///
820                /// # Examples
821                ///
822                /// Basic usage:
823                ///
824                #[doc = concat!(" ```", $doctest_attr)]
825                /// # use arbitrary_int::u14;
826                /// assert_eq!(u14::new(0x1).checked_shl(4), Some(u14::new(0x10)));
827                /// assert_eq!(u14::new(0x10).checked_shl(129), None);
828                /// assert_eq!(u14::new(0x10).checked_shl(13), Some(u14::new(0)));
829                /// ```
830                #[inline]
831                #[must_use = "this returns the result of the operation, without modifying the original"]
832                pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
833                    if rhs >= (BITS as u32) {
834                        None
835                    } else {
836                        Some(Self {
837                            value: (self.value() << rhs) & Self::MASK,
838                        })
839                    }
840                }
841
842                /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is larger than
843                /// or equal to the number of bits in `self`.
844                ///
845                /// # Examples
846                ///
847                /// Basic usage:
848                ///
849                #[doc = concat!(" ```", $doctest_attr)]
850                /// # use arbitrary_int::u14;
851                /// assert_eq!(u14::new(0x10).checked_shr(4), Some(u14::new(0x1)));
852                /// assert_eq!(u14::new(0x10).checked_shr(129), None);
853                /// ```
854                #[inline]
855                #[must_use = "this returns the result of the operation, without modifying the original"]
856                pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
857                    if rhs >= (BITS as u32) {
858                        None
859                    } else {
860                        Some(Self {
861                            value: self.value() >> rhs,
862                        })
863                    }
864                }
865
866                /// Calculates `self + rhs`.
867                ///
868                /// Returns a tuple of the addition along with a boolean indicating whether an arithmetic
869                /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
870                ///
871                /// # Examples
872                ///
873                /// Basic usage:
874                ///
875                #[doc = concat!(" ```", $doctest_attr)]
876                /// # use arbitrary_int::prelude::*;
877                /// assert_eq!(u14::new(5).overflowing_add(u14::new(2)), (u14::new(7), false));
878                /// assert_eq!(u14::MAX.overflowing_add(u14::new(1)), (u14::new(0), true));
879                /// ```
880                #[inline]
881                #[must_use = "this returns the result of the operation, without modifying the original"]
882                pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
883                    let (value, overflow) = if Self::UNUSED_BITS == 0 {
884                        // We are something like a UInt::<u8; 8>, we can fallback to the base implementation.
885                        // This is very unlikely to happen in practice, but checking allows us to use
886                        // `wrapping_add` instead of `overflowing_add` in the common case, which is faster.
887                        self.value().overflowing_add(rhs.value())
888                    } else {
889                        // We're dealing with fewer bits than the underlying type (e.g. u7).
890                        // That means the addition can never overflow the underlying type
891                        let sum = self.value().wrapping_add(rhs.value());
892                        let masked = sum & Self::MASK;
893                        (masked, masked != sum)
894                    };
895
896                    (Self { value }, overflow)
897                }
898
899                /// Calculates `self - rhs`.
900                ///
901                /// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic
902                /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
903                ///
904                /// # Examples
905                ///
906                /// Basic usage:
907                ///
908                #[doc = concat!(" ```", $doctest_attr)]
909                /// # use arbitrary_int::prelude::*;
910                /// assert_eq!(u14::new(5).overflowing_sub(u14::new(2)), (u14::new(3), false));
911                /// assert_eq!(u14::new(0).overflowing_sub(u14::new(1)), (u14::MAX, true));
912                /// ```
913                #[inline]
914                #[must_use = "this returns the result of the operation, without modifying the original"]
915                pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
916                    // For unsigned numbers, the only difference is when we reach 0 - which is the same
917                    // no matter the data size. In the case of overflow we do have the mask the result though
918                    let (value, overflow) = self.value().overflowing_sub(rhs.value());
919                    (Self { value: value & Self::MASK }, overflow)
920                }
921
922                /// Calculates the multiplication of `self` and `rhs`.
923                ///
924                /// Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic
925                /// overflow would occur. If an overflow would have occurred then the wrapped value is returned.
926                ///
927                /// # Examples
928                ///
929                /// Basic usage:
930                ///
931                #[doc = concat!(" ```", $doctest_attr)]
932                /// # use arbitrary_int::prelude::*;
933                /// assert_eq!(u14::new(5).overflowing_mul(u14::new(2)), (u14::new(10), false));
934                /// assert_eq!(u14::new(1_000).overflowing_mul(u14::new(1000)), (u14::new(576), true));
935                /// ```
936                #[inline]
937                #[must_use = "this returns the result of the operation, without modifying the original"]
938                pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
939                    let (wrapping_product, overflow) = if (BITS << 1) <= (core::mem::size_of::<$type>() << 3) {
940                        // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type.
941                        // `wrapping_mul` likely provides the best performance on all CPUs.
942                        (self.value().wrapping_mul(rhs.value()), false)
943                    } else {
944                        // We have more than half the bits (e.g. u6 * u6)
945                        self.value().overflowing_mul(rhs.value())
946                    };
947
948                    let masked = wrapping_product & Self::MASK;
949                    let overflow2 = masked != wrapping_product;
950                    (Self { value: masked }, overflow || overflow2)
951                }
952
953                /// Calculates the divisor when `self` is divided by `rhs`.
954                ///
955                /// Returns a tuple of the divisor along with a boolean indicating whether an arithmetic
956                /// overflow would occur. Note that for unsigned integers overflow never occurs, so the
957                /// second value is always false.
958                ///
959                /// # Panics
960                ///
961                /// This function will panic if `rhs` is `zero`.
962                ///
963                /// # Examples
964                ///
965                /// Basic usage:
966                ///
967                #[doc = concat!(" ```", $doctest_attr)]
968                /// # use arbitrary_int::prelude::*;
969                /// assert_eq!(u14::new(5).overflowing_div(u14::new(2)), (u14::new(2), false));
970                /// ```
971                #[inline]
972                #[must_use = "this returns the result of the operation, without modifying the original"]
973                pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
974                    let value = self.value().wrapping_div(rhs.value());
975                    (Self { value }, false)
976                }
977
978                /// Shifts `self` left by `rhs` bits.
979                ///
980                /// Returns a tuple of the shifted version of `self` along with a boolean indicating whether
981                /// the shift value was larger than or equal to the number of bits. If the shift value is too
982                /// large, then value is masked (`N-1`) where `N` is the number of bits, and this value is then
983                /// used to perform the shift.
984                ///
985                /// # Examples
986                ///
987                /// Basic usage:
988                ///
989                #[doc = concat!(" ```", $doctest_attr)]
990                /// # use arbitrary_int::prelude::*;
991                /// assert_eq!(u14::new(0x1).overflowing_shl(4), (u14::new(0x10), false));
992                /// assert_eq!(u14::new(0x1).overflowing_shl(132), (u14::new(0x40), true));
993                /// assert_eq!(u14::new(0x10).overflowing_shl(13), (u14::new(0), false));
994                /// ```
995                #[inline]
996                #[must_use = "this returns the result of the operation, without modifying the original"]
997                pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
998                    let (shift, overflow) = if rhs >= (BITS as u32) {
999                        (rhs % (BITS as u32), true)
1000                    } else {
1001                        (rhs, false)
1002                    };
1003
1004                    // This cannot possibly wrap as we've already limited `shift` to `BITS`.
1005                    let value = self.value().wrapping_shl(shift);
1006                    (Self { value }, overflow)
1007                }
1008
1009                /// Shifts `self` right by `rhs` bits.
1010                ///
1011                /// Returns a tuple of the shifted version of `self` along with a boolean indicating whether
1012                /// the shift value was larger than or equal to the number of bits. If the shift value is too
1013                /// large, then value is masked (`N-1`) where `N` is the number of bits, and this value is then
1014                /// used to perform the shift.
1015                ///
1016                /// # Examples
1017                ///
1018                /// Basic usage:
1019                ///
1020                #[doc = concat!(" ```", $doctest_attr)]
1021                /// # use arbitrary_int::prelude::*;
1022                /// assert_eq!(u14::new(0x10).overflowing_shr(4), (u14::new(0x1), false));
1023                /// assert_eq!(u14::new(0x10).overflowing_shr(113), (u14::new(0x8), true));
1024                /// ```
1025                #[inline]
1026                #[must_use = "this returns the result of the operation, without modifying the original"]
1027                pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
1028                    let (shift, overflow) = if rhs >= (BITS as u32) {
1029                        (rhs % (BITS as u32), true)
1030                    } else {
1031                        (rhs, false)
1032                    };
1033
1034                    // This cannot possibly wrap as we've already limited `shift` to `BITS`.
1035                    let value = self.value().wrapping_shr(shift);
1036                    (Self { value }, overflow)
1037                }
1038
1039                /// Reverses the order of bits in the integer. The least significant bit becomes the most
1040                /// significant bit, second least-significant bit becomes second most-significant bit, etc.
1041                ///
1042                /// # Examples
1043                ///
1044                /// Basic usage:
1045                ///
1046                #[doc = concat!(" ```", $doctest_attr)]
1047                /// # use arbitrary_int::prelude::*;
1048                /// assert_eq!(u6::new(0b10_1010).reverse_bits(), u6::new(0b01_0101));
1049                /// assert_eq!(u6::new(0), u6::new(0).reverse_bits());
1050                /// ```
1051                #[inline]
1052                #[must_use = "this returns the result of the operation, without modifying the original"]
1053                pub const fn reverse_bits(self) -> Self {
1054                    Self { value: self.value().reverse_bits() >> Self::UNUSED_BITS }
1055                }
1056
1057                /// Returns the number of ones in the binary representation of `self`.
1058                ///
1059                /// # Examples
1060                ///
1061                /// Basic usage:
1062                ///
1063                #[doc = concat!(" ```", $doctest_attr)]
1064                /// # use arbitrary_int::prelude::*;
1065                /// let n = u7::new(0b100_1100);
1066                /// assert_eq!(n.count_ones(), 3);
1067                ///
1068                /// let max = u7::MAX;
1069                /// assert_eq!(max.count_ones(), 7);
1070                ///
1071                /// let zero = u7::new(0);
1072                /// assert_eq!(zero.count_ones(), 0);
1073                /// ```
1074                #[inline]
1075                pub const fn count_ones(self) -> u32 {
1076                    // The upper bits are zero, so we can ignore them
1077                    self.value().count_ones()
1078                }
1079
1080                /// Returns the number of zeros in the binary representation of `self`.
1081                ///
1082                /// # Examples
1083                ///
1084                /// Basic usage:
1085                ///
1086                #[doc = concat!(" ```", $doctest_attr)]
1087                /// # use arbitrary_int::prelude::*;
1088                /// let zero = u7::new(0);
1089                /// assert_eq!(zero.count_zeros(), 7);
1090                ///
1091                /// let max = u7::MAX;
1092                /// assert_eq!(max.count_zeros(), 0);
1093                /// ```
1094                #[inline]
1095                pub const fn count_zeros(self) -> u32 {
1096                    // The upper bits are zero, so we can have to subtract them from the result.
1097                    // We can avoid a bounds check in debug builds with `wrapping_sub` since this cannot overflow.
1098                    self.value().count_zeros().wrapping_sub(Self::UNUSED_BITS as u32)
1099                }
1100
1101                /// Returns the number of leading ones in the binary representation of `self`.
1102                ///
1103                /// # Examples
1104                ///
1105                /// Basic usage:
1106                ///
1107                #[doc = concat!(" ```", $doctest_attr)]
1108                /// # use arbitrary_int::prelude::*;
1109                /// let n = !(u7::MAX >> 2);
1110                /// assert_eq!(n.leading_ones(), 2);
1111                ///
1112                /// let zero = u7::new(0);
1113                /// assert_eq!(zero.leading_ones(), 0);
1114                ///
1115                /// let max = u7::MAX;
1116                /// assert_eq!(max.leading_ones(), 7);
1117                /// ```
1118                #[inline]
1119                pub const fn leading_ones(self) -> u32 {
1120                    (self.value() << Self::UNUSED_BITS).leading_ones()
1121                }
1122
1123                /// Returns the number of leading zeros in the binary representation of `self`.
1124                ///
1125                /// # Examples
1126                ///
1127                /// Basic usage:
1128                ///
1129                #[doc = concat!(" ```", $doctest_attr)]
1130                /// # use arbitrary_int::prelude::*;
1131                /// let n = u7::MAX >> 2;
1132                /// assert_eq!(n.leading_zeros(), 2);
1133                ///
1134                /// let zero = u7::new(0);
1135                /// assert_eq!(zero.leading_zeros(), 7);
1136                ///
1137                /// let max = u7::MAX;
1138                /// assert_eq!(max.leading_zeros(), 0);
1139                /// ```
1140                #[inline]
1141                pub const fn leading_zeros(self) -> u32 {
1142                    if Self::UNUSED_BITS == 0 {
1143                        self.value().leading_zeros()
1144                    } else {
1145                        // Prevent an all-zero value reporting the underlying type's entire bit width by setting
1146                        // the first unused bit to one, causing `leading_zeros()` to ignore the unused bits.
1147                        let first_unused_bit_set = const { 1 << (Self::UNUSED_BITS - 1) };
1148                        ((self.value() << Self::UNUSED_BITS) | first_unused_bit_set).leading_zeros()
1149                    }
1150                }
1151
1152                /// Returns the number of trailing ones in the binary representation of `self`.
1153                ///
1154                /// # Examples
1155                ///
1156                /// Basic usage:
1157                ///
1158                #[doc = concat!(" ```", $doctest_attr)]
1159                /// # use arbitrary_int::prelude::*;
1160                /// let n = u7::new(0b1010111);
1161                /// assert_eq!(n.trailing_ones(), 3);
1162                ///
1163                /// let zero = u7::new(0);
1164                /// assert_eq!(zero.trailing_ones(), 0);
1165                ///
1166                /// let max = u7::MAX;
1167                /// assert_eq!(max.trailing_ones(), 7);
1168                /// ```
1169                #[inline]
1170                pub const fn trailing_ones(self) -> u32 {
1171                    self.value().trailing_ones()
1172                }
1173
1174                /// Returns the number of trailing zeros in the binary representation of `self`.
1175                ///
1176                /// # Examples
1177                ///
1178                /// Basic usage:
1179                ///
1180                #[doc = concat!(" ```", $doctest_attr)]
1181                /// # use arbitrary_int::prelude::*;
1182                /// let n = u7::new(0b010_1000);
1183                /// assert_eq!(n.trailing_zeros(), 3);
1184                ///
1185                /// let zero = u7::new(0);
1186                /// assert_eq!(zero.trailing_zeros(), 7);
1187                ///
1188                /// let max = u7::MAX;
1189                /// assert_eq!(max.trailing_zeros(), 0);
1190                /// ```
1191                #[inline]
1192                pub const fn trailing_zeros(self) -> u32 {
1193                    // Prevent an all-zeros value reporting the underlying type's entire bit width by setting
1194                    // all the unused bits.
1195                    (self.value() | !Self::MASK).trailing_zeros()
1196                }
1197
1198                /// Shifts the bits to the left by a specified amount, `n`, wrapping the truncated bits
1199                /// to the end of the resulting integer.
1200                ///
1201                /// Please note this isn’t the same operation as the `<<` shifting operator!
1202                ///
1203                /// # Examples
1204                ///
1205                /// Basic usage:
1206                ///
1207                #[doc = concat!(" ```", $doctest_attr)]
1208                /// # use arbitrary_int::prelude::*;
1209                /// let n = u6::new(0b10_1010);
1210                /// let m = u6::new(0b01_0101);
1211                ///
1212                /// assert_eq!(n.rotate_left(1), m);
1213                /// ```
1214                #[inline]
1215                #[must_use = "this returns the result of the operation, without modifying the original"]
1216                pub const fn rotate_left(self, n: u32) -> Self {
1217                    let b = BITS as u32;
1218                    let n = if n >= b { n % b } else { n };
1219
1220                    let moved_bits = (self.value() << n) & Self::MASK;
1221                    let truncated_bits = self.value() >> (b - n);
1222                    Self { value: moved_bits | truncated_bits }
1223                }
1224
1225                /// Shifts the bits to the right by a specified amount, `n`, wrapping the truncated bits
1226                /// to the beginning of the resulting integer.
1227                ///
1228                /// Please note this isn’t the same operation as the `>>` shifting operator!
1229                ///
1230                /// # Examples
1231                ///
1232                /// Basic usage:
1233                ///
1234                #[doc = concat!(" ```", $doctest_attr)]
1235                /// # use arbitrary_int::prelude::*;
1236                /// let n = u6::new(0b10_1010);
1237                /// let m = u6::new(0b01_0101);
1238                ///
1239                /// assert_eq!(n.rotate_right(1), m);
1240                /// ```
1241                #[inline]
1242                #[must_use = "this returns the result of the operation, without modifying the original"]
1243                pub const fn rotate_right(self, n: u32) -> Self {
1244                    let b = BITS as u32;
1245                    let n = if n >= b { n % b } else { n };
1246
1247                    let moved_bits = self.value() >> n;
1248                    let truncated_bits = (self.value() << (b - n)) & Self::MASK;
1249                    Self { value: moved_bits | truncated_bits }
1250                }
1251            }
1252        )+
1253    };
1254}
1255
1256// Because the methods within this macro are effectively copy-pasted for each underlying integer type,
1257// each documentation test gets executed five times (once for each underlying type), even though the
1258// tests themselves aren't specific to said underlying type. This severely slows down `cargo test`,
1259// so we ignore them for all but one (arbitrary) underlying type.
1260uint_impl!(
1261    (u8, doctest = "rust"),
1262    (u16, doctest = "ignore"),
1263    (u32, doctest = "ignore"),
1264    (u64, doctest = "ignore"),
1265    (u128, doctest = "ignore")
1266);
1267
1268// Arithmetic implementations
1269impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Add for UInt<T, BITS>
1270where
1271    Self: UnsignedInteger,
1272{
1273    type Output = UInt<T, BITS>;
1274
1275    fn add(self, rhs: Self) -> Self::Output {
1276        let sum = self.value + rhs.value;
1277        #[cfg(debug_assertions)]
1278        if (sum & !Self::MASK) != T::ZERO {
1279            panic!("attempt to add with overflow");
1280        }
1281        Self {
1282            value: sum & Self::MASK,
1283        }
1284    }
1285}
1286
1287impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> AddAssign for UInt<T, BITS>
1288where
1289    Self: UnsignedInteger,
1290{
1291    fn add_assign(&mut self, rhs: Self) {
1292        self.value += rhs.value;
1293        #[cfg(debug_assertions)]
1294        if (self.value & !Self::MASK) != T::ZERO {
1295            panic!("attempt to add with overflow");
1296        }
1297        self.value &= Self::MASK;
1298    }
1299}
1300
1301impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Sub for UInt<T, BITS>
1302where
1303    Self: Integer,
1304{
1305    type Output = UInt<T, BITS>;
1306
1307    fn sub(self, rhs: Self) -> Self::Output {
1308        // No need for extra overflow checking as the regular minus operator already handles it for us
1309        Self {
1310            value: (self.value - rhs.value) & Self::MASK,
1311        }
1312    }
1313}
1314
1315impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> SubAssign for UInt<T, BITS>
1316where
1317    Self: Integer,
1318{
1319    fn sub_assign(&mut self, rhs: Self) {
1320        // No need for extra overflow checking as the regular minus operator already handles it for us
1321        self.value -= rhs.value;
1322        self.value &= Self::MASK;
1323    }
1324}
1325
1326impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Mul for UInt<T, BITS>
1327where
1328    Self: Integer,
1329{
1330    type Output = UInt<T, BITS>;
1331
1332    fn mul(self, rhs: Self) -> Self::Output {
1333        // In debug builds, this will perform two bounds checks: Initial multiplication, followed by
1334        // our bounds check. As wrapping_mul isn't available as a trait bound (in regular Rust), this
1335        // is unavoidable
1336        let product = self.value * rhs.value;
1337        #[cfg(debug_assertions)]
1338        if (product & !Self::MASK) != T::ZERO {
1339            panic!("attempt to multiply with overflow");
1340        }
1341        Self {
1342            value: product & Self::MASK,
1343        }
1344    }
1345}
1346
1347impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> MulAssign for UInt<T, BITS>
1348where
1349    Self: Integer,
1350{
1351    fn mul_assign(&mut self, rhs: Self) {
1352        self.value *= rhs.value;
1353        #[cfg(debug_assertions)]
1354        if (self.value & !Self::MASK) != T::ZERO {
1355            panic!("attempt to multiply with overflow");
1356        }
1357        self.value &= Self::MASK;
1358    }
1359}
1360
1361impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Div for UInt<T, BITS> {
1362    type Output = UInt<T, BITS>;
1363
1364    fn div(self, rhs: Self) -> Self::Output {
1365        // Integer division can only make the value smaller. And as the result is same type as
1366        // Self, there's no need to range-check or mask
1367        Self {
1368            value: self.value / rhs.value,
1369        }
1370    }
1371}
1372
1373impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> DivAssign for UInt<T, BITS> {
1374    fn div_assign(&mut self, rhs: Self) {
1375        self.value /= rhs.value;
1376    }
1377}
1378
1379impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitAnd for UInt<T, BITS> {
1380    type Output = UInt<T, BITS>;
1381
1382    fn bitand(self, rhs: Self) -> Self::Output {
1383        Self {
1384            value: self.value & rhs.value,
1385        }
1386    }
1387}
1388
1389impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitAndAssign for UInt<T, BITS> {
1390    fn bitand_assign(&mut self, rhs: Self) {
1391        self.value &= rhs.value;
1392    }
1393}
1394
1395impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitOr for UInt<T, BITS> {
1396    type Output = UInt<T, BITS>;
1397
1398    fn bitor(self, rhs: Self) -> Self::Output {
1399        Self {
1400            value: self.value | rhs.value,
1401        }
1402    }
1403}
1404
1405impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitOrAssign for UInt<T, BITS> {
1406    fn bitor_assign(&mut self, rhs: Self) {
1407        self.value |= rhs.value;
1408    }
1409}
1410
1411impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitXor for UInt<T, BITS> {
1412    type Output = UInt<T, BITS>;
1413
1414    fn bitxor(self, rhs: Self) -> Self::Output {
1415        Self {
1416            value: self.value ^ rhs.value,
1417        }
1418    }
1419}
1420
1421impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> BitXorAssign for UInt<T, BITS> {
1422    fn bitxor_assign(&mut self, rhs: Self) {
1423        self.value ^= rhs.value;
1424    }
1425}
1426
1427impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Not for UInt<T, BITS>
1428where
1429    Self: Integer,
1430{
1431    type Output = UInt<T, BITS>;
1432
1433    fn not(self) -> Self::Output {
1434        Self {
1435            value: self.value ^ Self::MASK,
1436        }
1437    }
1438}
1439
1440impl<
1441        T: BuiltinInteger + UnsignedInteger + Shl<TSHIFTBITS, Output = T>,
1442        TSHIFTBITS: TryInto<usize> + Copy,
1443        const BITS: usize,
1444    > Shl<TSHIFTBITS> for UInt<T, BITS>
1445where
1446    Self: Integer,
1447{
1448    type Output = UInt<T, BITS>;
1449
1450    fn shl(self, rhs: TSHIFTBITS) -> Self::Output {
1451        // With debug assertions, the << and >> operators throw an exception if the shift amount
1452        // is larger than the number of bits (in which case the result would always be 0)
1453        #[cfg(debug_assertions)]
1454        if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1455            panic!("attempt to shift left with overflow")
1456        }
1457
1458        Self {
1459            value: (self.value << rhs) & Self::MASK,
1460        }
1461    }
1462}
1463
1464impl<
1465        T: BuiltinInteger + UnsignedInteger + ShlAssign<TSHIFTBITS>,
1466        TSHIFTBITS: TryInto<usize> + Copy,
1467        const BITS: usize,
1468    > ShlAssign<TSHIFTBITS> for UInt<T, BITS>
1469where
1470    Self: Integer,
1471{
1472    fn shl_assign(&mut self, rhs: TSHIFTBITS) {
1473        // With debug assertions, the << and >> operators throw an exception if the shift amount
1474        // is larger than the number of bits (in which case the result would always be 0)
1475        #[cfg(debug_assertions)]
1476        if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1477            panic!("attempt to shift left with overflow")
1478        }
1479        self.value <<= rhs;
1480        self.value &= Self::MASK;
1481    }
1482}
1483
1484impl<
1485        T: BuiltinInteger + UnsignedInteger + Shr<TSHIFTBITS, Output = T>,
1486        TSHIFTBITS: TryInto<usize> + Copy,
1487        const BITS: usize,
1488    > Shr<TSHIFTBITS> for UInt<T, BITS>
1489{
1490    type Output = UInt<T, BITS>;
1491
1492    fn shr(self, rhs: TSHIFTBITS) -> Self::Output {
1493        // With debug assertions, the << and >> operators throw an exception if the shift amount
1494        // is larger than the number of bits (in which case the result would always be 0)
1495        #[cfg(debug_assertions)]
1496        if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1497            panic!("attempt to shift left with overflow")
1498        }
1499        Self {
1500            value: self.value >> rhs,
1501        }
1502    }
1503}
1504
1505impl<
1506        T: BuiltinInteger + UnsignedInteger + ShrAssign<TSHIFTBITS>,
1507        TSHIFTBITS: TryInto<usize> + Copy,
1508        const BITS: usize,
1509    > ShrAssign<TSHIFTBITS> for UInt<T, BITS>
1510{
1511    fn shr_assign(&mut self, rhs: TSHIFTBITS) {
1512        // With debug assertions, the << and >> operators throw an exception if the shift amount
1513        // is larger than the number of bits (in which case the result would always be 0)
1514        #[cfg(debug_assertions)]
1515        if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
1516            panic!("attempt to shift left with overflow")
1517        }
1518        self.value >>= rhs;
1519    }
1520}
1521
1522impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Display for UInt<T, BITS> {
1523    #[inline]
1524    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1525        Display::fmt(&self.value, f)
1526    }
1527}
1528
1529impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Debug for UInt<T, BITS> {
1530    #[inline]
1531    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1532        Debug::fmt(&self.value, f)
1533    }
1534}
1535
1536impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> LowerHex for UInt<T, BITS> {
1537    #[inline]
1538    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1539        LowerHex::fmt(&self.value, f)
1540    }
1541}
1542
1543impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> UpperHex for UInt<T, BITS> {
1544    #[inline]
1545    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1546        UpperHex::fmt(&self.value, f)
1547    }
1548}
1549
1550impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Octal for UInt<T, BITS> {
1551    #[inline]
1552    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1553        Octal::fmt(&self.value, f)
1554    }
1555}
1556
1557impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> Binary for UInt<T, BITS> {
1558    #[inline]
1559    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1560        Binary::fmt(&self.value, f)
1561    }
1562}
1563
1564#[cfg(feature = "defmt")]
1565impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> defmt::Format for UInt<T, BITS>
1566where
1567    T: defmt::Format,
1568{
1569    #[inline]
1570    fn format(&self, f: defmt::Formatter) {
1571        self.value.format(f)
1572    }
1573}
1574
1575impl_borsh!(UInt, "u", UnsignedInteger);
1576
1577#[cfg(feature = "serde")]
1578impl<T: BuiltinInteger + UnsignedInteger, const BITS: usize> serde::Serialize for UInt<T, BITS>
1579where
1580    T: serde::Serialize,
1581{
1582    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1583        self.value.serialize(serializer)
1584    }
1585}
1586
1587// Serde's invalid_value error (https://rust-lang.github.io/hashbrown/serde/de/trait.Error.html#method.invalid_value)
1588// takes an Unexpected (https://rust-lang.github.io/hashbrown/serde/de/enum.Unexpected.html) which only accepts a 64 bit
1589// unsigned integer. This is a problem for us because we want to support 128 bit unsigned integers. To work around this
1590// we define our own error type using the UInt's underlying type which implements Display and then use
1591// serde::de::Error::custom to create an error with our custom type.
1592#[cfg(feature = "serde")]
1593struct InvalidUIntValueError<T: UnsignedInteger> {
1594    value: T::UnderlyingType,
1595}
1596
1597#[cfg(feature = "serde")]
1598impl<T: UnsignedInteger> Display for InvalidUIntValueError<T> {
1599    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1600        write!(
1601            f,
1602            "invalid value: integer `{}`, expected a value between `0` and `{}`",
1603            self.value,
1604            T::MAX.value()
1605        )
1606    }
1607}
1608
1609#[cfg(feature = "serde")]
1610impl<'de, T: BuiltinInteger + UnsignedInteger, const BITS: usize> serde::Deserialize<'de>
1611    for UInt<T, BITS>
1612where
1613    Self: UnsignedInteger<UnderlyingType = T>,
1614    T: serde::Deserialize<'de>,
1615{
1616    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1617        let value = T::deserialize(deserializer)?;
1618
1619        if value <= Self::MAX.value {
1620            Ok(Self { value })
1621        } else {
1622            let err = InvalidUIntValueError::<Self> { value };
1623            Err(serde::de::Error::custom(err))
1624        }
1625    }
1626}
1627
1628// Implement `core::iter::Sum` and `core::iter::Product`.
1629impl_sum_product!(UInt, 1_u8, UnsignedInteger);
1630
1631// Implement support for the `num-traits` crate, if the feature is enabled.
1632impl_num_traits!(UInt, UnsignedInteger, u8, |value| value & Self::MASK);
1633
1634// Implement `core::iter::Step` (if the `step_trait` feature is enabled).
1635impl_step!(UInt, UnsignedInteger);
1636
1637// Implement byte operations for UInt's with a bit width aligned to a byte boundary.
1638
1639// Support for the `schemars` crate, if the feature is enabled.
1640impl_schemars!(UInt, "uint", UnsignedInteger);
1641
1642bytes_operation_impl!(UInt<u32, 24>, u32);
1643bytes_operation_impl!(UInt<u64, 24>, u64);
1644bytes_operation_impl!(UInt<u128, 24>, u128);
1645bytes_operation_impl!(UInt<u64, 40>, u64);
1646bytes_operation_impl!(UInt<u128, 40>, u128);
1647bytes_operation_impl!(UInt<u64, 48>, u64);
1648bytes_operation_impl!(UInt<u128, 48>, u128);
1649bytes_operation_impl!(UInt<u64, 56>, u64);
1650bytes_operation_impl!(UInt<u128, 56>, u128);
1651bytes_operation_impl!(UInt<u128, 72>, u128);
1652bytes_operation_impl!(UInt<u128, 80>, u128);
1653bytes_operation_impl!(UInt<u128, 88>, u128);
1654bytes_operation_impl!(UInt<u128, 96>, u128);
1655bytes_operation_impl!(UInt<u128, 104>, u128);
1656bytes_operation_impl!(UInt<u128, 112>, u128);
1657bytes_operation_impl!(UInt<u128, 120>, u128);
1658
1659// Conversions
1660from_arbitrary_int_impl!(UInt(u8), [u16, u32, u64, u128]);
1661from_arbitrary_int_impl!(UInt(u16), [u8, u32, u64, u128]);
1662from_arbitrary_int_impl!(UInt(u32), [u8, u16, u64, u128]);
1663from_arbitrary_int_impl!(UInt(u64), [u8, u16, u32, u128]);
1664from_arbitrary_int_impl!(UInt(u128), [u8, u32, u64, u16]);
1665
1666from_native_impl!(UInt(u8), [u8, u16, u32, u64, u128]);
1667from_native_impl!(UInt(u16), [u8, u16, u32, u64, u128]);
1668from_native_impl!(UInt(u32), [u8, u16, u32, u64, u128]);
1669from_native_impl!(UInt(u64), [u8, u16, u32, u64, u128]);
1670from_native_impl!(UInt(u128), [u8, u16, u32, u64, u128]);
1671
1672pub use aliases::*;
1673
1674#[allow(non_camel_case_types)]
1675#[rustfmt::skip]
1676pub(crate) mod aliases {
1677    use crate::common::type_alias;
1678
1679    type_alias!(UInt(u8), (u1, 1), (u2, 2), (u3, 3), (u4, 4), (u5, 5), (u6, 6), (u7, 7));
1680    type_alias!(UInt(u16), (u9, 9), (u10, 10), (u11, 11), (u12, 12), (u13, 13), (u14, 14), (u15, 15));
1681    type_alias!(UInt(u32), (u17, 17), (u18, 18), (u19, 19), (u20, 20), (u21, 21), (u22, 22), (u23, 23), (u24, 24), (u25, 25), (u26, 26), (u27, 27), (u28, 28), (u29, 29), (u30, 30), (u31, 31));
1682    type_alias!(UInt(u64), (u33, 33), (u34, 34), (u35, 35), (u36, 36), (u37, 37), (u38, 38), (u39, 39), (u40, 40), (u41, 41), (u42, 42), (u43, 43), (u44, 44), (u45, 45), (u46, 46), (u47, 47), (u48, 48), (u49, 49), (u50, 50), (u51, 51), (u52, 52), (u53, 53), (u54, 54), (u55, 55), (u56, 56), (u57, 57), (u58, 58), (u59, 59), (u60, 60), (u61, 61), (u62, 62), (u63, 63));
1683    type_alias!(UInt(u128), (u65, 65), (u66, 66), (u67, 67), (u68, 68), (u69, 69), (u70, 70), (u71, 71), (u72, 72), (u73, 73), (u74, 74), (u75, 75), (u76, 76), (u77, 77), (u78, 78), (u79, 79), (u80, 80), (u81, 81), (u82, 82), (u83, 83), (u84, 84), (u85, 85), (u86, 86), (u87, 87), (u88, 88), (u89, 89), (u90, 90), (u91, 91), (u92, 92), (u93, 93), (u94, 94), (u95, 95), (u96, 96), (u97, 97), (u98, 98), (u99, 99), (u100, 100), (u101, 101), (u102, 102), (u103, 103), (u104, 104), (u105, 105), (u106, 106), (u107, 107), (u108, 108), (u109, 109), (u110, 110), (u111, 111), (u112, 112), (u113, 113), (u114, 114), (u115, 115), (u116, 116), (u117, 117), (u118, 118), (u119, 119), (u120, 120), (u121, 121), (u122, 122), (u123, 123), (u124, 124), (u125, 125), (u126, 126), (u127, 127));
1684}
1685
1686macro_rules! boolu1 {
1687    ($($const_keyword:ident)?) => {
1688        impl $($const_keyword)? From<bool> for u1 {
1689            #[inline]
1690            fn from(value: bool) -> Self {
1691                u1::new(value as u8)
1692            }
1693        }
1694
1695        impl $($const_keyword)? From<u1> for bool {
1696            #[inline]
1697            fn from(value: u1) -> Self {
1698                match value.value() {
1699                    0 => false,
1700                    1 => true,
1701                    _ => unreachable!(), // TODO: unreachable!() is not const yet
1702                }
1703            }
1704        }
1705    };
1706}
1707
1708#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
1709boolu1!();
1710
1711#[cfg(feature = "const_convert_and_const_trait_impl")]
1712boolu1!(const);