#![cfg_attr(not(feature = "std"), no_std)]
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(core_intrinsics)]
use core::{marker::PhantomData, fmt::Debug, ops::Rem};
pub mod group;
pub mod ring;
pub mod field;
pub struct Element<I, M: Modular<I>>(pub I, PhantomData<M>);
pub trait Modular<E> {
const P: E;
}
pub trait PrimeModular<E>: Modular<E> { }
pub trait OddModular<E>: Modular<E> { }
impl<I: Copy, M: Modular<I>> Clone for Element<I, M> {
fn clone(&self) -> Self {
Element(self.0, PhantomData)
}
}
impl<I: Copy, M: Modular<I>> Copy for Element<I, M> { }
impl<I, M: Modular<I>> From<I> for Element<I, M>
where
I: Rem<Output = I>
{
fn from(value: I) -> Self {
Element::new(value)
}
}
impl<I, M: Modular<I>> Element<I, M>
where
I: Rem<Output = I>
{
pub fn new(value: I) -> Self {
Element(value % M::P, PhantomData)
}
}
impl<I, M: Modular<I>> Element<I, M> {
pub const fn new_unchecked(value: I) -> Self {
Element(value, PhantomData)
}
}
impl<I, M: Modular<I>> Element<I, M> {
pub const fn repr(&self) -> &I {
&self.0
}
pub const fn modular() -> I {
M::P
}
}
impl<I: Debug, M: Modular<I>> Debug for Element<I, M> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl<I: PartialEq, M: Modular<I>> PartialEq for Element<I, M> {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<I: Eq, M: Modular<I>> Eq for Element<I, M> { }
impl<I: PartialOrd, M: Modular<I>> PartialOrd for Element<I, M> {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl<I: Ord, M: Modular<I>> Ord for Element<I, M> {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.0.cmp(&other.0)
}
}