1use super::{
4 small_uint::{U1, U2, U4},
5 underlier_type::{NumCast, UnderlierType},
6 underlier_with_bit_ops::UnderlierWithBitOps,
7};
8use crate::arch::{interleave_mask_even, interleave_with_mask};
9
10macro_rules! impl_underlier_type {
11 ($name:ty) => {
12 impl UnderlierType for $name {
13 const LOG_BITS: usize =
14 binius_utils::checked_arithmetics::checked_log_2(Self::BITS as _);
15 }
16 };
17 () => {};
18 ($name:ty, $($tail:ty),+) => {
19 impl_underlier_type!($name);
20 impl_underlier_type!($($tail),+);
21 }
22}
23
24impl_underlier_type!(u8, u16, u32, u64, u128);
25
26impl UnderlierWithBitOps for u8 {
27 const ZERO: Self = 0;
28 const ONE: Self = 1;
29 const ONES: Self = Self::MAX;
30
31 fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self) {
32 const MASKS: &[u8] = &[
33 interleave_mask_even!(u8, 0),
34 interleave_mask_even!(u8, 1),
35 interleave_mask_even!(u8, 2),
36 ];
37 interleave_with_mask(self, other, log_block_len, MASKS)
38 }
39}
40
41impl UnderlierWithBitOps for u16 {
42 const ZERO: Self = 0;
43 const ONE: Self = 1;
44 const ONES: Self = Self::MAX;
45
46 fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self) {
47 const MASKS: &[u16] = &[
48 interleave_mask_even!(u16, 0),
49 interleave_mask_even!(u16, 1),
50 interleave_mask_even!(u16, 2),
51 interleave_mask_even!(u16, 3),
52 ];
53 interleave_with_mask(self, other, log_block_len, MASKS)
54 }
55}
56
57impl UnderlierWithBitOps for u32 {
58 const ZERO: Self = 0;
59 const ONE: Self = 1;
60 const ONES: Self = Self::MAX;
61
62 fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self) {
63 const MASKS: &[u32] = &[
64 interleave_mask_even!(u32, 0),
65 interleave_mask_even!(u32, 1),
66 interleave_mask_even!(u32, 2),
67 interleave_mask_even!(u32, 3),
68 interleave_mask_even!(u32, 4),
69 ];
70 interleave_with_mask(self, other, log_block_len, MASKS)
71 }
72}
73
74impl UnderlierWithBitOps for u64 {
75 const ZERO: Self = 0;
76 const ONE: Self = 1;
77 const ONES: Self = Self::MAX;
78
79 fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self) {
80 const MASKS: &[u64] = &[
81 interleave_mask_even!(u64, 0),
82 interleave_mask_even!(u64, 1),
83 interleave_mask_even!(u64, 2),
84 interleave_mask_even!(u64, 3),
85 interleave_mask_even!(u64, 4),
86 interleave_mask_even!(u64, 5),
87 ];
88 interleave_with_mask(self, other, log_block_len, MASKS)
89 }
90}
91
92impl UnderlierWithBitOps for u128 {
93 const ZERO: Self = 0;
94 const ONE: Self = 1;
95 const ONES: Self = Self::MAX;
96
97 fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self) {
98 const MASKS: &[u128] = &[
99 interleave_mask_even!(u128, 0),
100 interleave_mask_even!(u128, 1),
101 interleave_mask_even!(u128, 2),
102 interleave_mask_even!(u128, 3),
103 interleave_mask_even!(u128, 4),
104 interleave_mask_even!(u128, 5),
105 interleave_mask_even!(u128, 6),
106 ];
107 interleave_with_mask(self, other, log_block_len, MASKS)
108 }
109}
110
111macro_rules! impl_num_cast {
112 (@pair U1, U2) => {impl_num_cast!(@small_u_from_small_u U1, U2);};
113 (@pair U1, U4) => {impl_num_cast!(@small_u_from_small_u U1, U4);};
114 (@pair U2, U4) => {impl_num_cast!(@small_u_from_small_u U2, U4);};
115 (@pair U1, $bigger:ty) => {impl_num_cast!(@small_u_from_u U1, $bigger);};
116 (@pair U2, $bigger:ty) => {impl_num_cast!(@small_u_from_u U2, $bigger);};
117 (@pair U4, $bigger:ty) => {impl_num_cast!(@small_u_from_u U4, $bigger);};
118 (@pair $smaller:ident, $bigger:ident) => {
119 impl NumCast<$bigger> for $smaller {
120 #[inline(always)]
121 fn num_cast_from(val: $bigger) -> Self {
122 val as _
123 }
124 }
125
126 impl NumCast<$smaller> for $bigger {
127 #[inline(always)]
128 fn num_cast_from(val: $smaller) -> Self {
129 val as _
130 }
131 }
132 };
133 (@small_u_from_small_u $smaller:ty, $bigger:ty) => {
134 impl NumCast<$bigger> for $smaller {
135 #[inline(always)]
136 fn num_cast_from(val: $bigger) -> Self {
137 Self::new(val.val()) & Self::ONES
138 }
139 }
140
141 impl NumCast<$smaller> for $bigger {
142 #[inline(always)]
143 fn num_cast_from(val: $smaller) -> Self {
144 Self::new(val.val())
145 }
146 }
147 };
148 (@small_u_from_u $smaller:ty, $bigger:ty) => {
149 impl NumCast<$bigger> for $smaller {
150 #[inline(always)]
151 fn num_cast_from(val: $bigger) -> Self {
152 Self::new(val as u8) & Self::ONES
153 }
154 }
155
156 impl NumCast<$smaller> for $bigger {
157 #[inline(always)]
158 fn num_cast_from(val: $smaller) -> Self {
159 val.val() as _
160 }
161 }
162 };
163 ($_:ty,) => {};
164 (,) => {};
165 (all_pairs) => {};
166 (all_pairs $_:ty) => {};
167 (all_pairs $_:ty,) => {};
168 (all_pairs $smaller:ident, $head:ident, $($tail:ident,)*) => {
169 impl_num_cast!(@pair $smaller, $head);
170 impl_num_cast!(all_pairs $smaller, $($tail,)*);
171 };
172 ($smaller:ident, $($tail:ident,)+) => {
173 impl_num_cast!(all_pairs $smaller, $($tail,)+);
174 impl_num_cast!($($tail,)+);
175 };
176}
177
178impl_num_cast!(U1, U2, U4, u8, u16, u32, u64, u128,);