Skip to main content

arbitrary_int/
unsigned.rs

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