use crate::Belt;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use arrayvec::ArrayVec;
pub trait Element: Clone {
fn is_zero(&self) -> bool;
}
impl Element for Belt {
#[inline(always)]
fn is_zero(&self) -> bool {
self.is_zero()
}
}
pub trait Poly {
type Element: Element;
fn data(&self) -> &[Self::Element];
#[inline(always)]
fn degree(&self) -> u32 {
self.data()
.iter()
.rposition(|x| !Element::is_zero(x))
.map_or(0, |i| i as u32)
}
#[inline(always)]
fn is_zero(&self) -> bool {
let len = self.len();
let data = self.data();
if len == 0 || (len == 1 && data[0].is_zero()) {
return true;
}
data.iter().all(|x| x.is_zero())
}
#[inline(always)]
fn len(&self) -> usize {
self.data().len()
}
}
impl<T> Poly for &[T]
where
T: Element,
{
type Element = T;
#[inline(always)]
fn data(&self) -> &[T] {
self
}
}
#[cfg(feature = "alloc")]
impl<T> Poly for Vec<T>
where
T: Element,
{
type Element = T;
#[inline(always)]
fn data(&self) -> &[T] {
self.as_slice()
}
}
impl<T, const MAX_POLY_SIZE: usize> Poly for ArrayVec<T, MAX_POLY_SIZE>
where
T: Element,
{
type Element = T;
#[inline(always)]
fn data(&self) -> &[T] {
self.as_slice()
}
}
impl<T> Poly for &mut [T]
where
T: Element,
{
type Element = T;
#[inline(always)]
fn data(&self) -> &[T] {
self
}
}