use std::ops::MulAssign;
use symbolica::atom::{Atom, AtomView};
use super::{to_param::ToAtom, ConcreteOrParam, ConcreteOrParamRef};
impl<T, U> MulAssign<ConcreteOrParam<U>> for ConcreteOrParam<T>
where
Atom: MulAssign<U> + MulAssign<Atom>,
T: ToAtom + MulAssign<U>,
{
fn mul_assign(&mut self, rhs: ConcreteOrParam<U>) {
match (self, rhs) {
(ConcreteOrParam::Concrete(c1), ConcreteOrParam::Concrete(c2)) => *c1 *= c2,
(ConcreteOrParam::Param(a), ConcreteOrParam::Concrete(c)) => *a *= c,
(ConcreteOrParam::Param(a1), ConcreteOrParam::Param(a2)) => *a1 *= a2,
(c, a) => {
c.to_param();
*c *= a
}
}
}
}
impl<T, U> MulAssign<&ConcreteOrParam<U>> for ConcreteOrParam<T>
where
Atom: for<'a> MulAssign<&'a U> + for<'a> MulAssign<&'a Atom>,
T: ToAtom + for<'a> MulAssign<&'a U>,
{
fn mul_assign(&mut self, rhs: &ConcreteOrParam<U>) {
match (self, rhs) {
(ConcreteOrParam::Concrete(c1), ConcreteOrParam::Concrete(c2)) => *c1 *= c2,
(ConcreteOrParam::Param(a), ConcreteOrParam::Concrete(c)) => *a *= c,
(ConcreteOrParam::Param(a1), ConcreteOrParam::Param(a2)) => *a1 *= a2,
(c, a) => {
c.to_param();
*c *= a
}
}
}
}
impl<T, U> MulAssign<ConcreteOrParamRef<'_, U>> for ConcreteOrParam<T>
where
Atom: MulAssign<U> + for<'a> MulAssign<AtomView<'a>>,
T: ToAtom + MulAssign<U>,
{
fn mul_assign(&mut self, rhs: ConcreteOrParamRef<'_, U>) {
match (self, rhs) {
(ConcreteOrParam::Concrete(c1), ConcreteOrParamRef::Concrete(c2)) => *c1 *= c2,
(ConcreteOrParam::Param(a), ConcreteOrParamRef::Concrete(c)) => *a *= c,
(ConcreteOrParam::Param(a1), ConcreteOrParamRef::Param(a2)) => *a1 *= a2,
(c, a) => {
c.to_param();
*c *= a
}
}
}
}
impl<T> MulAssign<ConcreteOrParamRef<'_, T>> for Atom
where
Atom: MulAssign<T> + for<'a> MulAssign<AtomView<'a>>,
{
fn mul_assign(&mut self, rhs: ConcreteOrParamRef<'_, T>) {
match rhs {
ConcreteOrParamRef::Concrete(c) => *self *= c,
ConcreteOrParamRef::Param(a) => *self *= a,
}
}
}
impl<T> MulAssign<ConcreteOrParam<T>> for Atom
where
Atom: MulAssign<T> + MulAssign<Atom>,
{
fn mul_assign(&mut self, rhs: ConcreteOrParam<T>) {
match rhs {
ConcreteOrParam::Concrete(c) => *self *= c,
ConcreteOrParam::Param(a) => *self *= a,
}
}
}