binius_field/underlier/
underlier_type.rs1use std::fmt::Debug;
4
5use bytemuck::{NoUninit, Zeroable};
6use rand::distr::{Distribution, StandardUniform};
7use subtle::ConstantTimeEq;
8
9pub trait UnderlierType:
12 Debug
13 + Default
14 + PartialEq
15 + Eq
16 + PartialOrd
17 + Ord
18 + ConstantTimeEq
19 + Copy
20 + Random
21 + NoUninit
22 + Zeroable
23 + Sized
24 + Send
25 + Sync
26 + 'static
27{
28 const LOG_BITS: usize;
30 const BITS: usize = 1 << Self::LOG_BITS;
33}
34
35pub unsafe trait WithUnderlier: Sized + Zeroable + Copy + Send + Sync + 'static {
46 type Underlier: UnderlierType;
48
49 fn to_underlier(self) -> Self::Underlier;
51
52 fn to_underlier_ref(&self) -> &Self::Underlier;
53
54 fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier;
55
56 fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier];
57
58 fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier];
59
60 fn to_underliers_arr<const N: usize>(val: [Self; N]) -> [Self::Underlier; N] {
61 val.map(Self::to_underlier)
62 }
63
64 fn to_underliers_arr_ref<const N: usize>(val: &[Self; N]) -> &[Self::Underlier; N] {
65 Self::to_underliers_ref(val)
66 .try_into()
67 .expect("array size is valid")
68 }
69
70 fn to_underliers_arr_ref_mut<const N: usize>(val: &mut [Self; N]) -> &mut [Self::Underlier; N] {
71 Self::to_underliers_ref_mut(val)
72 .try_into()
73 .expect("array size is valid")
74 }
75
76 fn from_underlier(val: Self::Underlier) -> Self;
77
78 fn from_underlier_ref(val: &Self::Underlier) -> &Self;
79
80 fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self;
81
82 fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self];
83
84 fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self];
85
86 fn from_underliers_arr<const N: usize>(val: [Self::Underlier; N]) -> [Self; N] {
87 val.map(Self::from_underlier)
88 }
89
90 fn from_underliers_arr_ref<const N: usize>(val: &[Self::Underlier; N]) -> &[Self; N] {
91 Self::from_underliers_ref(val)
92 .try_into()
93 .expect("array size is valid")
94 }
95
96 fn from_underliers_arr_ref_mut<const N: usize>(
97 val: &mut [Self::Underlier; N],
98 ) -> &mut [Self; N] {
99 Self::from_underliers_ref_mut(val)
100 .try_into()
101 .expect("array size is valid")
102 }
103
104 #[inline]
105 fn mutate_underlier(self, f: impl FnOnce(Self::Underlier) -> Self::Underlier) -> Self {
106 Self::from_underlier(f(self.to_underlier()))
107 }
108}
109
110unsafe impl<U: UnderlierType> WithUnderlier for U {
111 type Underlier = U;
112
113 #[inline]
114 fn to_underlier(self) -> Self::Underlier {
115 self
116 }
117
118 #[inline]
119 fn to_underlier_ref(&self) -> &Self::Underlier {
120 self
121 }
122
123 #[inline]
124 fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier {
125 self
126 }
127
128 #[inline]
129 fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier] {
130 val
131 }
132
133 #[inline]
134 fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier] {
135 val
136 }
137
138 #[inline]
139 fn from_underlier(val: Self::Underlier) -> Self {
140 val
141 }
142
143 #[inline]
144 fn from_underlier_ref(val: &Self::Underlier) -> &Self {
145 val
146 }
147
148 #[inline]
149 fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self {
150 val
151 }
152
153 #[inline]
154 fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self] {
155 val
156 }
157
158 #[inline]
159 fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self] {
160 val
161 }
162}
163
164pub trait Random {
166 fn random(rng: impl rand::Rng) -> Self;
168}
169
170impl<T> Random for T
171where
172 StandardUniform: Distribution<T>,
173{
174 fn random(mut rng: impl rand::Rng) -> Self {
175 rng.random()
176 }
177}
178
179pub trait NumCast<From> {
182 fn num_cast_from(val: From) -> Self;
183}
184
185impl<U: UnderlierType> NumCast<U> for U {
186 #[inline(always)]
187 fn num_cast_from(val: U) -> Self {
188 val
189 }
190}