pub trait ConstantFolding {
type Error;
type T;
fn constant_fold(&mut self) -> Result<(), Self::Error>;
fn constant_folded(mut self) -> Result<Self, Self::Error>
where
Self: Sized,
{
self.constant_fold()?;
Ok(self)
}
fn const_value(&self) -> Option<Self::T> {
None
}
}
impl<E: ConstantFolding> ConstantFolding for Vec<E> {
type Error = E::Error;
type T = Vec<E::T>;
fn constant_fold(&mut self) -> Result<(), Self::Error> {
self.iter_mut().try_for_each(|e| e.constant_fold())
}
fn const_value(&self) -> Option<Self::T> {
self.iter().map(|e| e.const_value()).collect()
}
}
impl<E: ConstantFolding> ConstantFolding for [E] {
type Error = E::Error;
type T = Vec<E::T>;
fn constant_fold(&mut self) -> Result<(), Self::Error> {
self.iter_mut().try_for_each(|e| e.constant_fold())
}
fn const_value(&self) -> Option<Self::T> {
self.iter().map(|e| e.const_value()).collect()
}
}
pub trait Canonicalize {
fn canonicalize(&mut self);
fn canonicalized(mut self) -> Self
where
Self: Sized,
{
self.canonicalize();
self
}
}
impl<E: Canonicalize> Canonicalize for Vec<E> {
fn canonicalize(&mut self) {
for e in self {
e.canonicalize();
}
}
}
impl<E: Canonicalize> Canonicalize for [E] {
fn canonicalize(&mut self) {
for e in self {
e.canonicalize();
}
}
}