binius_field/underlier/
underlier_type.rs1use std::{
4 fmt::Debug,
5 ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl, Shr},
6};
7
8use bytemuck::{NoUninit, TransparentWrapper, Zeroable};
9
10use super::{U1, underlier_with_bit_ops::spread_fallback};
11use crate::{Divisible, Random};
12
13pub trait UnderlierType:
16 Debug
17 + Default
18 + Eq
19 + Ord
20 + Copy
21 + Random
22 + NoUninit
23 + Zeroable
24 + Sized
25 + Send
26 + Sync
27 + 'static
28 + BitAnd<Self, Output = Self>
29 + BitAndAssign<Self>
30 + BitOr<Self, Output = Self>
31 + BitOrAssign<Self>
32 + BitXor<Self, Output = Self>
33 + BitXorAssign<Self>
34 + Shr<usize, Output = Self>
35 + Shl<usize, Output = Self>
36 + Not<Output = Self>
37 + Divisible<U1>
38{
39 const LOG_BITS: usize;
41 const BITS: usize = 1 << Self::LOG_BITS;
44
45 const ZERO: Self;
46 const ONE: Self;
47 const ONES: Self;
48
49 fn fill_with_bit(val: u8) -> Self {
52 Self::broadcast_subvalue(U1::new(val))
53 }
54
55 fn interleave(self, other: Self, log_block_len: usize) -> (Self, Self);
57
58 fn transpose(mut self, mut other: Self, log_block_len: usize) -> (Self, Self) {
60 assert!(log_block_len < Self::LOG_BITS);
61
62 for log_block_len in (log_block_len..Self::LOG_BITS).rev() {
63 (self, other) = self.interleave(other, log_block_len);
64 }
65
66 (self, other)
67 }
68
69 #[inline]
70 fn from_fn<T>(f: impl FnMut(usize) -> T) -> Self
71 where
72 T: UnderlierType,
73 Self: Divisible<T>,
74 {
75 Self::from_iter((0..<Self as Divisible<T>>::N).map(f))
76 }
77
78 #[inline]
81 fn broadcast_subvalue<T>(value: T) -> Self
82 where
83 T: UnderlierType,
84 Self: Divisible<T>,
85 {
86 Divisible::<T>::broadcast(value)
87 }
88
89 #[inline]
96 unsafe fn spread<T>(self, log_block_len: usize, block_idx: usize) -> Self
97 where
98 T: UnderlierType,
99 Self: Divisible<T>,
100 {
101 unsafe { spread_fallback::<Self, T>(self, log_block_len, block_idx) }
102 }
103}
104
105pub unsafe trait WithUnderlier:
116 TransparentWrapper<Self::Underlier> + Sized + Zeroable + Copy + Send + Sync + 'static
117{
118 type Underlier: UnderlierType;
120
121 #[inline]
123 fn to_underlier(self) -> Self::Underlier {
124 Self::peel(self)
125 }
126
127 #[inline]
128 fn to_underlier_ref(&self) -> &Self::Underlier {
129 Self::peel_ref(self)
130 }
131
132 #[inline]
133 fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier {
134 Self::peel_mut(self)
135 }
136
137 #[inline]
138 fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier] {
139 Self::peel_slice(val)
140 }
141
142 #[inline]
143 fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier] {
144 Self::peel_slice_mut(val)
145 }
146
147 #[inline]
148 fn to_underliers_arr<const N: usize>(val: [Self; N]) -> [Self::Underlier; N] {
149 val.map(Self::to_underlier)
150 }
151
152 #[inline]
153 fn to_underliers_arr_ref<const N: usize>(val: &[Self; N]) -> &[Self::Underlier; N] {
154 Self::to_underliers_ref(val)
155 .try_into()
156 .expect("array size is valid")
157 }
158
159 #[inline]
160 fn to_underliers_arr_ref_mut<const N: usize>(val: &mut [Self; N]) -> &mut [Self::Underlier; N] {
161 Self::to_underliers_ref_mut(val)
162 .try_into()
163 .expect("array size is valid")
164 }
165
166 #[inline]
167 fn from_underlier(val: Self::Underlier) -> Self {
168 Self::wrap(val)
169 }
170
171 #[inline]
172 fn from_underlier_ref(val: &Self::Underlier) -> &Self {
173 Self::wrap_ref(val)
174 }
175
176 #[inline]
177 fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self {
178 Self::wrap_mut(val)
179 }
180
181 #[inline]
182 fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self] {
183 Self::wrap_slice(val)
184 }
185
186 #[inline]
187 fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self] {
188 Self::wrap_slice_mut(val)
189 }
190
191 #[inline]
192 fn from_underliers_arr<const N: usize>(val: [Self::Underlier; N]) -> [Self; N] {
193 val.map(Self::from_underlier)
194 }
195
196 #[inline]
197 fn from_underliers_arr_ref<const N: usize>(val: &[Self::Underlier; N]) -> &[Self; N] {
198 Self::from_underliers_ref(val)
199 .try_into()
200 .expect("array size is valid")
201 }
202
203 #[inline]
204 fn from_underliers_arr_ref_mut<const N: usize>(
205 val: &mut [Self::Underlier; N],
206 ) -> &mut [Self; N] {
207 Self::from_underliers_ref_mut(val)
208 .try_into()
209 .expect("array size is valid")
210 }
211
212 #[inline]
213 fn mutate_underlier(self, f: impl FnOnce(Self::Underlier) -> Self::Underlier) -> Self {
214 Self::from_underlier(f(self.to_underlier()))
215 }
216}
217
218pub trait NumCast<From> {
221 fn num_cast_from(val: From) -> Self;
222}
223
224impl<U: UnderlierType> NumCast<U> for U {
225 #[inline(always)]
226 fn num_cast_from(val: U) -> Self {
227 val
228 }
229}