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 const BITS: usize;
54
55 const MIN: Self;
57
58 const MAX: Self;
60
61 fn new(value: Self::UnderlyingType) -> Self;
64
65 fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError>;
67
68 fn value(self) -> Self::UnderlyingType;
69
70 #[cfg(not(feature = "const_convert_and_const_trait_impl"))]
73 fn from_<T: Number>(value: T) -> Self;
74
75 #[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 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 #[cfg(not(feature = "hint"))]
214 #[inline]
215 pub const fn value(self) -> T {
216 self.value
217 }
218
219 #[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#[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 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 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 #[inline]
410 pub const fn new(value: $type) -> Self {
411 assert!(value <= Self::MAX.value);
412
413 Self { value }
414 }
415
416 #[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 #[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 #[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 #[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 #[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 #[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 #[cfg(feature = "hint")]
473 #[inline]
474 pub const fn value(self) -> $type {
475 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 let _ = Self::MAX;
491
492 Self {
493 value: (value >> start_bit) & Self::MAX.value,
494 }
495 }
496
497 #[inline]
501 pub const fn extract_u8(value: u8, start_bit: usize) -> Self {
502 assert!(start_bit + BITS <= 8);
503 let _ = Self::MAX;
505
506 Self {
507 value: ((value >> start_bit) as $type) & Self::MAX.value,
508 }
509 }
510
511 #[inline]
515 pub const fn extract_u16(value: u16, start_bit: usize) -> Self {
516 assert!(start_bit + BITS <= 16);
517 let _ = Self::MAX;
519
520 Self {
521 value: ((value >> start_bit) as $type) & Self::MAX.value,
522 }
523 }
524
525 #[inline]
529 pub const fn extract_u32(value: u32, start_bit: usize) -> Self {
530 assert!(start_bit + BITS <= 32);
531 let _ = Self::MAX;
533
534 Self {
535 value: ((value >> start_bit) as $type) & Self::MAX.value,
536 }
537 }
538
539 #[inline]
543 pub const fn extract_u64(value: u64, start_bit: usize) -> Self {
544 assert!(start_bit + BITS <= 64);
545 let _ = Self::MAX;
547
548 Self {
549 value: ((value >> start_bit) as $type) & Self::MAX.value,
550 }
551 }
552
553 #[inline]
557 pub const fn extract_u128(value: u128, start_bit: usize) -> Self {
558 assert!(start_bit + BITS <= 128);
559 let _ = Self::MAX;
561
562 Self {
563 value: ((value >> start_bit) as $type) & Self::MAX.value,
564 }
565 }
566
567 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 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 value: sum,
606 }
607 }
608
609 pub const fn wrapping_shl(self, rhs: u32) -> Self {
610 let shift_amount = if rhs >= (BITS as u32) {
612 rhs % (BITS as u32)
613 } else {
614 rhs
615 };
616
617 Self {
618 value: (self.value << shift_amount) & Self::MASK,
623 }
624 }
625
626 pub const fn wrapping_shr(self, rhs: u32) -> Self {
627 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 self.value.saturating_add(rhs.value)
643 } else {
644 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 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 self.value.wrapping_mul(rhs.value)
668 } else {
669 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 Self {
685 value: self.value.saturating_div(rhs.value),
686 }
687 }
688
689 pub const fn saturating_pow(self, exp: u32) -> Self {
690 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 match self.value.checked_add(rhs.value) {
704 Some(value) => Some(Self { value }),
705 None => None
706 }
707 } else {
708 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 Some(self.value.wrapping_mul(rhs.value))
727 } else {
728 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 self.value.overflowing_add(rhs.value)
775 } else {
776 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 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 self.value.overflowing_mul(rhs.value)
797 } else {
798 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 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 pub const fn count_ones(self) -> u32 {
836 self.value.count_ones()
838 }
839
840 pub const fn count_zeros(self) -> u32 {
842 let filler_bits = ((core::mem::size_of::<$type>() << 3) - BITS) as u32;
844 self.value.count_zeros() - filler_bits
845 }
846
847 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 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 pub const fn trailing_ones(self) -> u32 {
861 self.value.trailing_ones()
862 }
863
864 pub const fn trailing_zeros(self) -> u32 {
866 self.value.trailing_zeros()
867 }
868
869 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 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
897impl<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 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 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 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 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 #[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 #[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 #[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 #[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 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 reader.read(&mut buf[..serialized_byte_count])?;
1329
1330 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#[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 ..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 #[inline]
1549 pub const fn swap_bytes(&self) -> Self {
1550 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#[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
1767macro_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#[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"), }
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!();