binius_field/underlier/
underlier_type.rs1use std::fmt::Debug;
4
5use bytemuck::{NoUninit, Zeroable};
6use rand::{
7 distributions::{Distribution, Standard},
8 Rng, RngCore,
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 {
48 type Underlier: UnderlierType;
50
51 fn to_underlier(self) -> Self::Underlier;
53
54 fn to_underlier_ref(&self) -> &Self::Underlier;
55
56 fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier;
57
58 fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier];
59
60 fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier];
61
62 fn to_underliers_arr<const N: usize>(val: [Self; N]) -> [Self::Underlier; N] {
63 val.map(Self::to_underlier)
64 }
65
66 fn to_underliers_arr_ref<const N: usize>(val: &[Self; N]) -> &[Self::Underlier; N] {
67 Self::to_underliers_ref(val)
68 .try_into()
69 .expect("array size is valid")
70 }
71
72 fn to_underliers_arr_ref_mut<const N: usize>(val: &mut [Self; N]) -> &mut [Self::Underlier; N] {
73 Self::to_underliers_ref_mut(val)
74 .try_into()
75 .expect("array size is valid")
76 }
77
78 fn from_underlier(val: Self::Underlier) -> Self;
79
80 fn from_underlier_ref(val: &Self::Underlier) -> &Self;
81
82 fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self;
83
84 fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self];
85
86 fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self];
87
88 fn from_underliers_arr<const N: usize>(val: [Self::Underlier; N]) -> [Self; N] {
89 val.map(Self::from_underlier)
90 }
91
92 fn from_underliers_arr_ref<const N: usize>(val: &[Self::Underlier; N]) -> &[Self; N] {
93 Self::from_underliers_ref(val)
94 .try_into()
95 .expect("array size is valid")
96 }
97
98 fn from_underliers_arr_ref_mut<const N: usize>(
99 val: &mut [Self::Underlier; N],
100 ) -> &mut [Self; N] {
101 Self::from_underliers_ref_mut(val)
102 .try_into()
103 .expect("array size is valid")
104 }
105
106 #[inline]
107 fn mutate_underlier(self, f: impl FnOnce(Self::Underlier) -> Self::Underlier) -> Self {
108 Self::from_underlier(f(self.to_underlier()))
109 }
110}
111
112unsafe impl<U: UnderlierType> WithUnderlier for U {
113 type Underlier = U;
114
115 #[inline]
116 fn to_underlier(self) -> Self::Underlier {
117 self
118 }
119
120 #[inline]
121 fn to_underlier_ref(&self) -> &Self::Underlier {
122 self
123 }
124
125 #[inline]
126 fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier {
127 self
128 }
129
130 #[inline]
131 fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier] {
132 val
133 }
134
135 #[inline]
136 fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier] {
137 val
138 }
139
140 #[inline]
141 fn from_underlier(val: Self::Underlier) -> Self {
142 val
143 }
144
145 #[inline]
146 fn from_underlier_ref(val: &Self::Underlier) -> &Self {
147 val
148 }
149
150 #[inline]
151 fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self {
152 val
153 }
154
155 #[inline]
156 fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self] {
157 val
158 }
159
160 #[inline]
161 fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self] {
162 val
163 }
164}
165
166pub trait Random {
168 fn random(rng: impl RngCore) -> Self;
170}
171
172impl<T> Random for T
173where
174 Standard: Distribution<T>,
175{
176 fn random(mut rng: impl RngCore) -> Self {
177 rng.gen()
178 }
179}
180
181pub trait NumCast<From> {
184 fn num_cast_from(val: From) -> Self;
185}
186
187impl<U: UnderlierType> NumCast<U> for U {
188 #[inline(always)]
189 fn num_cast_from(val: U) -> Self {
190 val
191 }
192}