Skip to main content

arbitrary_int/
unsigned.rs

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