bit_struct/
types.rs

1//! New integer types used in this crate, and trait implementations for those
2//! types
3
4use super::*;
5#[cfg(feature = "serde")]
6use serde::{Deserializer, Serializer};
7
8/// Assert that the given type is valid for any representation thereof
9macro_rules! always_valid {
10    ($($elem: ty),*) => {
11        $(
12        // Safety:
13        // This is correct: stdlib types are always valid
14        unsafe impl <P> ValidCheck<P> for $elem {
15            const ALWAYS_VALID: bool = true;
16        }
17        )*
18    };
19}
20
21/// Implement the [`BitCount`] trait easily for the built-in base types
22macro_rules! bit_counts {
23    ($($num: ty = $count: literal),*) => {
24        $(
25        // Safety:
26        // This is correct for the built-in types
27        unsafe impl BitCount for $num {
28            const COUNT: usize = $count;
29        }
30        )*
31    };
32}
33
34bit_counts!(u8 = 8, u16 = 16, u32 = 32, u64 = 64, u128 = 128, bool = 1);
35
36/// Implement the [`FieldStorage`] trait for some built-in types
37macro_rules! impl_field_storage {
38    ($(($type:ty, $base:ty)),+ $(,)?) => {
39        $(
40        impl FieldStorage for $type {
41            type StoredType = $base;
42
43            fn inner_raw(self) -> Self::StoredType {
44                self.into()
45            }
46        }
47        )+
48    };
49}
50impl_field_storage!(
51    (bool, u8),
52    (u8, Self),
53    (u16, Self),
54    (u32, Self),
55    (u64, Self),
56    (u128, Self),
57);
58macro_rules! impl_signed_field_storage {
59    ($(($type:ty, $base:ty)),+ $(,)?) => {
60        $(
61        impl FieldStorage for $type {
62            type StoredType = $base;
63
64            fn inner_raw(self) -> Self::StoredType {
65                <$base>::from_le_bytes(self.to_le_bytes())
66            }
67        }
68        )+
69    };
70}
71impl_signed_field_storage!((i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128),);
72
73always_valid!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool);
74/// Create a type for representing signed integers of sizes not provided by rust
75macro_rules! new_signed_types {
76    (
77        $($name: ident($count: literal, $inner: ty, $signed: ty)),*
78    ) => {
79        $(
80
81        #[doc = concat!("An unsigned integer which contains ", stringify!($count), " bits")]
82        #[allow(non_camel_case_types)]
83        #[derive(Copy, Clone, Eq, PartialEq, Hash)]
84        pub struct $name($inner);
85
86        always_valid!($name);
87
88        #[cfg(feature = "serde")]
89        impl serde::Serialize for $name {
90            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91            where
92                S: Serializer,
93            {
94                self.value().serialize(serializer)
95            }
96        }
97
98        #[cfg(feature = "serde")]
99        impl <'de> serde::Deserialize<'de> for $name {
100            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
101            where
102                D: Deserializer<'de>,
103            {
104                let inner = <$signed>::deserialize(deserializer)?;
105                $name::new(inner).ok_or(serde::de::Error::custom("invalid size"))
106            }
107        }
108
109        impl PartialOrd for $name {
110            fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
111                self.value().partial_cmp(&other.value())
112            }
113        }
114
115        impl Ord for $name {
116            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
117                self.value().cmp(&other.value())
118            }
119        }
120
121        impl Debug for $name {
122            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
123                f.write_fmt(format_args!("{}", self.value()))
124            }
125        }
126
127        impl Display for $name {
128            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
129                f.write_fmt(format_args!("{}", self.value()))
130            }
131        }
132
133        #[doc = concat!("Produce a value of type ", stringify!($name))]
134        ///
135        /// This macro checks at compile-time that it fits. To check at run-time see the
136        #[doc = concat!("[`", stringify!($name), "::new`] function.")]
137        #[macro_export]
138        macro_rules! $name {
139            ($value: expr) => {
140                {
141                    const VALUE: $signed = $value;
142                    const _: () = assert!(VALUE <= $crate::$name::MAX, "The provided value is too large");
143                    const _: () = assert!(VALUE >= $crate::$name::MIN, "The provided value is too small");
144                    let res: $name = unsafe {$crate::$name::new_unchecked(VALUE)};
145                    res
146                }
147            };
148        }
149
150        // Safety:
151        // This is guaranteed to be the correct arguments
152        unsafe impl BitCount for $name {
153            const COUNT: usize = $count;
154        }
155
156        num_traits!($name, $signed);
157
158        impl $name {
159            /// Create a new $name from value
160            /// # Safety
161            /// - value must fit within the number of bits defined in the type
162            pub const unsafe fn new_unchecked(value: $signed) -> Self {
163                let unsigned_value = value as $inner;
164                if value >= 0 {
165                    Self(unsigned_value)
166                } else {
167                    // we can do this
168                    let value = unsigned_value & Self::MAX_UNSIGNED;
169                    Self(value | Self::POLARITY_FLAG)
170                }
171            }
172
173
174            /// Create a new $name from value
175            /// # Safety
176            /// - value must fit within the number of bits defined in the type
177            pub fn new(value: $signed) -> Option<Self> {
178                if (Self::MIN..=Self::MAX).contains(&value) {
179                    // SAFETY:
180                    // We've just checked that this is safe to call
181                    Some(unsafe {Self::new_unchecked(value)})
182                } else {
183                    None
184                }
185            }
186
187            const POLARITY_FLAG: $inner = (1 << ($count - 1));
188            const MAX_UNSIGNED: $inner = (1 << ($count-1)) - 1;
189            /// The largest value this type can hold
190            pub const MAX: $signed = Self::MAX_UNSIGNED as $signed;
191            /// The smallest value this type can hold
192            pub const MIN: $signed = -(Self::MAX_UNSIGNED as $signed) - 1;
193
194            /// Get the value stored in here, as a signed integer
195            pub const fn value(self) -> $signed {
196                match self.0 >> ($count - 1) {
197                    0 => self.0 as $signed,
198                    _ => {
199                        // 0's out negative
200                        let rem = self.0 ^ Self::POLARITY_FLAG;
201                        let amount = Self::MAX_UNSIGNED - rem;
202                        -(amount as $signed) - 1
203                    }
204                }
205            }
206        }
207
208        impl Default for $name {
209            fn default() -> Self {
210                Self(0)
211            }
212        }
213
214        impl FieldStorage for $name {
215            type StoredType = $inner;
216
217            fn inner_raw(self) -> Self::StoredType {
218                self.0
219            }
220        }
221        )*
222    };
223}
224
225/// Implement traits from the [`num_traits`] crate for our new number types
226macro_rules! num_traits {
227    ($num:ident, $super_kind:ty) => {
228        impl Zero for $num {
229            fn zero() -> Self {
230                $num::new(0).unwrap()
231            }
232
233            fn is_zero(&self) -> bool {
234                self.0 == 0
235            }
236        }
237
238        impl Add for $num {
239            type Output = Self;
240
241            fn add(self, rhs: Self) -> Self::Output {
242                $num::new(self.value() + rhs.value()).unwrap()
243            }
244        }
245
246        impl One for $num {
247            fn one() -> Self {
248                $num::new(1).unwrap()
249            }
250        }
251
252        impl Mul for $num {
253            type Output = Self;
254
255            fn mul(self, rhs: Self) -> Self::Output {
256                $num::new(self.value() * rhs.value()).unwrap()
257            }
258        }
259
260        impl Sub for $num {
261            type Output = $num;
262
263            fn sub(self, rhs: Self) -> Self::Output {
264                $num::new(self.value() - rhs.value()).unwrap()
265            }
266        }
267
268        impl Div for $num {
269            type Output = Self;
270
271            fn div(self, rhs: Self) -> Self::Output {
272                $num::new(self.value() / rhs.value()).unwrap()
273            }
274        }
275
276        impl Rem for $num {
277            type Output = Self;
278
279            fn rem(self, rhs: Self) -> Self::Output {
280                $num::new(self.value() % rhs.value()).unwrap()
281            }
282        }
283
284        impl Num for $num {
285            type FromStrRadixErr = ();
286
287            fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
288                let parse = <$super_kind>::from_str_radix(str, radix).map_err(|_| ())?;
289                $num::new(parse).ok_or(())
290            }
291        }
292
293        impl ::core::str::FromStr for $num {
294            type Err = <Self as Num>::FromStrRadixErr;
295
296            fn from_str(s: &str) -> Result<Self, Self::Err> {
297                <Self as Num>::from_str_radix(s, 10)
298            }
299        }
300
301        impl Shr<usize> for $num {
302            type Output = $num;
303
304            fn shr(self, rhs: usize) -> Self::Output {
305                $num::new(self.value() >> rhs).unwrap()
306            }
307        }
308
309        impl Shl<usize> for $num {
310            type Output = $num;
311
312            fn shl(self, rhs: usize) -> Self::Output {
313                $num::new(self.value() << rhs).unwrap()
314            }
315        }
316
317        impl ShrAssign<usize> for $num {
318            fn shr_assign(&mut self, rhs: usize) {
319                let got = *self >> rhs;
320                *self = got;
321            }
322        }
323
324        impl ShlAssign<usize> for $num {
325            fn shl_assign(&mut self, rhs: usize) {
326                let got = *self << rhs;
327                *self = got;
328            }
329        }
330
331        impl Bounded for $num {
332            fn min_value() -> Self {
333                $num::new(Self::MIN).unwrap()
334            }
335
336            fn max_value() -> Self {
337                $num::new(Self::MAX).unwrap()
338            }
339        }
340
341        impl BitAnd for $num {
342            type Output = $num;
343
344            fn bitand(self, rhs: Self) -> Self::Output {
345                $num(self.0 & rhs.0)
346            }
347        }
348
349        impl BitXor for $num {
350            type Output = $num;
351
352            fn bitxor(self, rhs: Self) -> Self::Output {
353                $num(self.0 ^ rhs.0)
354            }
355        }
356
357        impl BitXorAssign for $num {
358            fn bitxor_assign(&mut self, rhs: Self) {
359                self.0 ^= rhs.0
360            }
361        }
362
363        impl BitAndAssign for $num {
364            fn bitand_assign(&mut self, rhs: Self) {
365                self.0 &= rhs.0
366            }
367        }
368
369        impl BitOr for $num {
370            type Output = Self;
371
372            fn bitor(self, rhs: Self) -> Self::Output {
373                $num(self.0 | rhs.0)
374            }
375        }
376
377        impl BitOrAssign for $num {
378            fn bitor_assign(&mut self, rhs: Self) {
379                self.0 |= rhs.0;
380            }
381        }
382    };
383}
384
385/// Create a type for representing unsigned integers of sizes not provided by
386/// rust
387macro_rules! new_unsigned_types {
388    (
389        $($name: ident($count: literal, $inner: ty)),*
390    ) => {
391        $(
392
393        #[doc = concat!("An unsigned integer which contains ", stringify!($count), " bits")]
394        #[allow(non_camel_case_types)]
395        #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
396        pub struct $name($inner);
397
398        always_valid!($name);
399
400        impl Debug for $name {
401            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
402                f.write_fmt(format_args!("{}", self.0))
403            }
404        }
405
406        impl Display for $name {
407            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
408                f.write_fmt(format_args!("{}", self.0))
409            }
410        }
411
412        #[cfg(feature = "serde")]
413        impl serde::Serialize for $name {
414            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
415            where
416                S: Serializer,
417            {
418                self.value().serialize(serializer)
419            }
420        }
421
422        #[cfg(feature = "serde")]
423        impl <'de> serde::Deserialize<'de> for $name {
424            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
425            where
426                D: Deserializer<'de>,
427            {
428                let inner = <$inner>::deserialize(deserializer)?;
429                $name::new(inner).ok_or(serde::de::Error::custom("invalid size"))
430            }
431        }
432
433        #[doc = concat!("Produce a value of type ", stringify!($name))]
434        ///
435        /// This macro checks at compile-time that it fits. To check at run-time see the
436        #[doc = concat!("[`", stringify!($name), "::new`] function.")]
437        #[macro_export]
438        macro_rules! $name {
439            ($value: literal) => {
440                {
441                    const VALUE: $inner = $value;
442
443                    // this is always valid because we have one more bit than we need in $inner
444                    // type
445                    const _: () = assert!($crate::$name::MAX >= VALUE, "The provided value is too large");
446                    unsafe {$crate::$name::new_unchecked(VALUE)}
447                }
448            };
449        }
450
451
452        // SAFETY:
453        // This is correct (guaranteed by macro arguments)
454        unsafe impl BitCount for $name {
455            /// The number of bits this type takes up
456            ///
457            /// Note that this is the conceptual amount it needs in a bit struct, not the amount it
458            /// will use as its own variable on the stack.
459            const COUNT: usize = $count;
460        }
461
462        impl $name {
463            /// The largest value that can be stored
464            pub const MAX: $inner = (1 << ($count)) - 1;
465            /// The smallest value that can be stored
466            pub const MIN: $inner = 0;
467
468            #[doc = concat!("Create a new ", stringify!($name), " from an inner value")]
469            ///
470            /// This method does not do any checks that the value passed is valid. To check that,
471            #[doc = concat!("use the [`", stringify!($name), "::new`] function.")]
472            ///
473            /// # Safety
474            /// The value must be valid value of the given type.
475            pub const unsafe fn new_unchecked(value: $inner) -> Self {
476                Self(value)
477            }
478
479            #[doc = concat!("Create a new ", stringify!($name), " from an inner value")]
480            ///
481            /// This method checks that the inner value is valid, and return `None` if it isn't.
482            pub fn new(value: $inner) -> Option<Self> {
483                if (Self::MIN..=Self::MAX).contains(&value) {
484                    // SAFETY:
485                    // We've checked that this is safe to do in the above `if`
486                    Some(unsafe {Self::new_unchecked(value)})
487                } else {
488                    None
489                }
490            }
491
492            /// Get the stored value
493            pub const fn value(self) -> $inner {
494                self.0
495            }
496        }
497
498        impl Default for $name {
499            fn default() -> Self {
500                Self(0)
501            }
502        }
503
504        num_traits!($name, $inner);
505
506        impl FieldStorage for $name {
507            type StoredType = $inner;
508
509            fn inner_raw(self) -> Self::StoredType {
510                self.0
511            }
512        }
513        )*
514    };
515}
516
517new_signed_types!(
518    i2(2, u8, i8),
519    i3(3, u8, i8),
520    i4(4, u8, i8),
521    i5(5, u8, i8),
522    i6(6, u8, i8),
523    i7(7, u8, i8),
524    i9(9, u16, i16),
525    i10(10, u16, i16),
526    i11(11, u16, i16),
527    i12(12, u16, i16),
528    i13(13, u16, i16),
529    i14(14, u16, i16),
530    i15(15, u16, i16),
531    i17(17, u32, i32),
532    i18(18, u32, i32),
533    i19(19, u32, i32),
534    i20(20, u32, i32),
535    i21(21, u32, i32),
536    i22(22, u32, i32),
537    i23(23, u32, i32),
538    i24(24, u32, i32),
539    i25(25, u32, i32),
540    i26(26, u32, i32),
541    i27(27, u32, i32),
542    i28(28, u32, i32),
543    i29(29, u32, i32),
544    i30(30, u32, i32),
545    i31(31, u32, i32),
546    i33(33, u64, i64),
547    i34(34, u64, i64),
548    i35(35, u64, i64),
549    i36(36, u64, i64),
550    i37(37, u64, i64),
551    i38(38, u64, i64),
552    i39(39, u64, i64),
553    i40(40, u64, i64),
554    i41(41, u64, i64),
555    i42(42, u64, i64),
556    i43(43, u64, i64),
557    i44(44, u64, i64),
558    i45(45, u64, i64),
559    i46(46, u64, i64),
560    i47(47, u64, i64),
561    i48(48, u64, i64),
562    i49(49, u64, i64),
563    i50(50, u64, i64),
564    i51(51, u64, i64),
565    i52(52, u64, i64),
566    i53(53, u64, i64),
567    i54(54, u64, i64),
568    i55(55, u64, i64),
569    i56(56, u64, i64),
570    i57(57, u64, i64),
571    i58(58, u64, i64),
572    i59(59, u64, i64),
573    i60(60, u64, i64),
574    i61(61, u64, i64),
575    i62(62, u64, i64),
576    i63(63, u64, i64)
577);
578
579new_unsigned_types!(
580    u1(1, u8),
581    u2(2, u8),
582    u3(3, u8),
583    u4(4, u8),
584    u5(5, u8),
585    u6(6, u8),
586    u7(7, u8),
587    u9(9, u16),
588    u10(10, u16),
589    u11(11, u16),
590    u12(12, u16),
591    u13(13, u16),
592    u14(14, u16),
593    u15(15, u16),
594    u17(17, u32),
595    u18(18, u32),
596    u19(19, u32),
597    u20(20, u32),
598    u21(21, u32),
599    u22(22, u32),
600    u23(23, u32),
601    u24(24, u32),
602    u25(25, u32),
603    u26(26, u32),
604    u27(27, u32),
605    u28(28, u32),
606    u29(29, u32),
607    u30(30, u32),
608    u31(31, u32),
609    u33(33, u64),
610    u34(34, u64),
611    u35(35, u64),
612    u36(36, u64),
613    u37(37, u64),
614    u38(38, u64),
615    u39(39, u64),
616    u40(40, u64),
617    u41(41, u64),
618    u42(42, u64),
619    u43(43, u64),
620    u44(44, u64),
621    u45(45, u64),
622    u46(46, u64),
623    u47(47, u64),
624    u48(48, u64),
625    u49(49, u64),
626    u50(50, u64),
627    u51(51, u64),
628    u52(52, u64),
629    u53(53, u64),
630    u54(54, u64),
631    u55(55, u64),
632    u56(56, u64),
633    u57(57, u64),
634    u58(58, u64),
635    u59(59, u64),
636    u60(60, u64),
637    u61(61, u64),
638    u62(62, u64),
639    u63(63, u64)
640);
641
642/// Implement functions for converting to/from byte arrays
643///
644/// Used for our numeric types that are an integer number of bytes.
645macro_rules! byte_from_impls {
646    ($($kind: ident: $super_kind: ty)*) => {
647        $(
648        impl $kind {
649            /// The size of byte array equal to this value
650            const ARR_SIZE: usize = <$kind>::COUNT / 8;
651            /// The size of byte array equal to the underlying storage for this value
652            const SUPER_BYTES: usize = ::core::mem::size_of::<$super_kind>();
653            /// Convert from an array of bytes, in big-endian order
654            pub fn from_be_bytes(bytes: [u8; Self::ARR_SIZE]) -> Self {
655                let mut res_bytes = [0_u8; Self::SUPER_BYTES];
656                for (set, &get) in res_bytes.iter_mut().rev().zip(bytes.iter().rev()) {
657                    *set = get;
658                }
659                Self(<$super_kind>::from_be_bytes(res_bytes))
660            }
661
662            /// Convert `self` into an array of bytes, in big-endian order
663            pub fn to_be_bytes(self) -> [u8; Self::ARR_SIZE] {
664                let mut res = [0; Self::ARR_SIZE];
665                let inner_bytes = self.0.to_be_bytes();
666                for (&get, set) in inner_bytes.iter().rev().zip(res.iter_mut().rev()) {
667                    *set = get;
668                }
669                res
670            }
671
672            /// Convert from an array of bytes, in little-endian order
673            pub fn from_le_bytes(bytes: [u8; Self::ARR_SIZE]) -> Self {
674                let mut res_bytes = [0_u8; Self::SUPER_BYTES];
675                for (set, &get) in res_bytes.iter_mut().zip(bytes.iter()) {
676                    *set = get;
677                }
678                Self(<$super_kind>::from_le_bytes(res_bytes))
679            }
680
681            /// Convert `self` into an array of bytes, in little-endian order
682            pub fn to_le_bytes(self) -> [u8; Self::ARR_SIZE] {
683                let mut res = [0; Self::ARR_SIZE];
684                let inner_bytes = self.0.to_le_bytes();
685                for (&get, set) in inner_bytes.iter().zip(res.iter_mut()) {
686                    *set = get;
687                }
688                res
689            }
690        }
691
692        impl From<u8> for $kind {
693            fn from(byte: u8) -> Self {
694                let inner = <$super_kind>::from(byte);
695                $kind(inner)
696            }
697        }
698        )*
699    };
700}
701
702byte_from_impls! {
703    u24: u32
704    u40: u64
705    u48: u64
706    u56: u64
707    i24: u32
708    i40: u64
709    i48: u64
710    i56: u64
711}
712
713impl u1 {
714    /// The 1-bit representation of true (1)
715    pub const TRUE: Self = Self(1);
716    /// The 1-bit representation of false (0)
717    pub const FALSE: Self = Self(0);
718
719    /// Get the opposite of this value (i.e. `TRUE` <--> `FALSE`)
720    #[must_use]
721    pub const fn toggle(self) -> Self {
722        match self {
723            Self::FALSE => Self::TRUE,
724            _ => Self::FALSE,
725        }
726    }
727}
728
729/// Implement `BitsFitIn` for the given pair of types, using the given method
730macro_rules! bits_fit_in_impl {
731    ($basety:ty => $target:ty : from) => {
732        impl BitsFitIn<$target> for $basety {
733            fn fit(self) -> $target {
734                self.inner_raw().into()
735            }
736        }
737    };
738    ($basety:ty => $target:ty : new_unchecked) => {
739        impl BitsFitIn<$target> for $basety {
740            fn fit(self) -> $target {
741                // Safety:
742                // The caller of this macro should only implement it with safe conversions
743                unsafe { <$target>::new_unchecked(self.inner_raw().into()) }
744            }
745        }
746    };
747}
748
749/// Implement `BitsFitIn` easily for a large number of unsigned types
750macro_rules! bits_fit_in_impls {
751    () => {};
752    (
753        // The types we generate from in this pass
754        ($basety:ty: $funcname:ident, $extra_ty:ty)
755        // The remaining target types
756        $( ,
757            ($first_target:ty: $target_funcname:ident $(, $extra_sources:ty)* $(,)?)
758        )* $(,)?
759    ) => {
760        bits_fit_in_impl!($basety => $basety: $funcname);
761        $(
762            bits_fit_in_impl!($basety => $first_target: $target_funcname);
763            bits_fit_in_impl!($extra_ty => $first_target: $target_funcname);
764        )*
765        bits_fit_in_impls!($(($first_target: $target_funcname $(, $extra_sources)*)),*);
766    }
767}
768
769bits_fit_in_impls!(
770    (u1: new_unchecked, bool),
771    (u2: new_unchecked, i2),
772    (u3: new_unchecked, i3),
773    (u4: new_unchecked, i4),
774    (u5: new_unchecked, i5),
775    (u6: new_unchecked, i6),
776    (u7: new_unchecked, i7),
777    (u8: from, i8),
778    (u9: new_unchecked, i9),
779    (u10: new_unchecked, i10),
780    (u11: new_unchecked, i11),
781    (u12: new_unchecked, i12),
782    (u13: new_unchecked, i13),
783    (u14: new_unchecked, i14),
784    (u15: new_unchecked, i15),
785    (u16: from, i16),
786    (u17: new_unchecked, i17),
787    (u18: new_unchecked, i18),
788    (u19: new_unchecked, i19),
789    (u20: new_unchecked, i20),
790    (u21: new_unchecked, i21),
791    (u22: new_unchecked, i22),
792    (u23: new_unchecked, i23),
793    (u24: new_unchecked, i24),
794    (u25: new_unchecked, i25),
795    (u26: new_unchecked, i26),
796    (u27: new_unchecked, i27),
797    (u28: new_unchecked, i28),
798    (u29: new_unchecked, i29),
799    (u30: new_unchecked, i30),
800    (u31: new_unchecked, i31),
801    (u32: from, i32),
802    (u33: new_unchecked, i33),
803    (u34: new_unchecked, i34),
804    (u35: new_unchecked, i35),
805    (u36: new_unchecked, i36),
806    (u37: new_unchecked, i37),
807    (u38: new_unchecked, i38),
808    (u39: new_unchecked, i39),
809    (u40: new_unchecked, i40),
810    (u41: new_unchecked, i41),
811    (u42: new_unchecked, i42),
812    (u43: new_unchecked, i43),
813    (u44: new_unchecked, i44),
814    (u45: new_unchecked, i45),
815    (u46: new_unchecked, i46),
816    (u47: new_unchecked, i47),
817    (u48: new_unchecked, i48),
818    (u49: new_unchecked, i49),
819    (u50: new_unchecked, i50),
820    (u51: new_unchecked, i51),
821    (u52: new_unchecked, i52),
822    (u53: new_unchecked, i53),
823    (u54: new_unchecked, i54),
824    (u55: new_unchecked, i55),
825    (u56: new_unchecked, i56),
826    (u57: new_unchecked, i57),
827    (u58: new_unchecked, i58),
828    (u59: new_unchecked, i59),
829    (u60: new_unchecked, i60),
830    (u61: new_unchecked, i61),
831    (u62: new_unchecked, i62),
832    (u63: new_unchecked, i63),
833    (u64: from, i64),
834);