arbitrary_int/
lib.rs

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