binius_field/underlier/
underlier_type.rsuse bytemuck::{NoUninit, Zeroable};
use rand::{
distributions::{Distribution, Standard},
Rng, RngCore,
};
use std::fmt::Debug;
use subtle::ConstantTimeEq;
pub trait UnderlierType:
Debug
+ Default
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ ConstantTimeEq
+ Copy
+ Random
+ NoUninit
+ Zeroable
+ Sized
+ Send
+ Sync
+ 'static
{
const LOG_BITS: usize;
const BITS: usize = 1 << Self::LOG_BITS;
}
pub unsafe trait WithUnderlier: Sized + Zeroable + Copy + Send + Sync + 'static {
type Underlier: UnderlierType;
fn to_underlier(self) -> Self::Underlier;
fn to_underlier_ref(&self) -> &Self::Underlier;
fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier;
fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier];
fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier];
fn from_underlier(val: Self::Underlier) -> Self;
fn from_underlier_ref(val: &Self::Underlier) -> &Self;
fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self;
fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self];
fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self];
#[inline]
fn mutate_underlier(self, f: impl FnOnce(Self::Underlier) -> Self::Underlier) -> Self {
Self::from_underlier(f(self.to_underlier()))
}
}
unsafe impl<U: UnderlierType> WithUnderlier for U {
type Underlier = U;
#[inline]
fn to_underlier(self) -> Self::Underlier {
self
}
#[inline]
fn to_underlier_ref(&self) -> &Self::Underlier {
self
}
#[inline]
fn to_underlier_ref_mut(&mut self) -> &mut Self::Underlier {
self
}
#[inline]
fn to_underliers_ref(val: &[Self]) -> &[Self::Underlier] {
val
}
#[inline]
fn to_underliers_ref_mut(val: &mut [Self]) -> &mut [Self::Underlier] {
val
}
#[inline]
fn from_underlier(val: Self::Underlier) -> Self {
val
}
#[inline]
fn from_underlier_ref(val: &Self::Underlier) -> &Self {
val
}
#[inline]
fn from_underlier_ref_mut(val: &mut Self::Underlier) -> &mut Self {
val
}
#[inline]
fn from_underliers_ref(val: &[Self::Underlier]) -> &[Self] {
val
}
#[inline]
fn from_underliers_ref_mut(val: &mut [Self::Underlier]) -> &mut [Self] {
val
}
}
pub trait Random {
fn random(rng: impl RngCore) -> Self;
}
impl<T> Random for T
where
Standard: Distribution<T>,
{
fn random(mut rng: impl RngCore) -> Self {
rng.gen()
}
}
pub trait NumCast<From> {
fn num_cast_from(val: From) -> Self;
}
impl<U: UnderlierType> NumCast<U> for U {
#[inline(always)]
fn num_cast_from(val: U) -> Self {
val
}
}