use crate::*;
pub trait PowDyn<
C,
D,
Rhs: ClosedAddDyn<D> + ClosedSubDyn<D> + ZeroDyn<D> + OneDyn<D> + EuclidDyn<D>,
>: Sized + Clone + ClosedMulDyn<C> + OneDyn<C>
{
fn pow_d(&self, rhs: &Rhs, ctx: &C, ctx2: &D) -> Self {
if rhs.is_zero_d(ctx2) {
return Self::one_d(ctx);
}
if rhs.is_one_d(ctx2) {
return self.clone();
}
let two = Rhs::one_d(ctx2).add_d(&Rhs::one_d(ctx2), ctx2);
let (q, r) = rhs.euclid_div_rem_d(&two, ctx2);
let mut x = self.pow_d(&q, ctx, ctx2);
x = x.mul_d(&x, ctx);
if r.is_one_d(ctx2) {
x.mul_assign_d(self, ctx);
}
x
}
}