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