use core::str::FromStr;
use malachite_base::num::arithmetic::traits::{ModAdd, ModIsReduced, ModMul, ModMulAssign};
use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
use malachite_base::test_util::generators::unsigned_vector_unsigned_unsigned_triple_gen_var_2;
use malachite_base::unsigned_vector::UnsignedVector;
use malachite_base::vector::Vector;
use std::panic::catch_unwind;
#[test]
fn test_mod_mul() {
let test = |s, c: u8, m: u8, out| {
let v = UnsignedVector::<u8>::from_str(s).unwrap();
let w = (&v).mod_mul(c, m);
assert_eq!(w.to_string(), out);
assert_eq!(v.clone().mod_mul(c, m), w);
let mut x = v;
x.mod_mul_assign(c, m);
assert_eq!(x, w);
};
test("()", 5, 7, "()");
test("(0, 0)", 0, 1, "(0, 0)");
test("(5, 1, 3)", 0, 7, "(0, 0, 0)");
test("(5, 1, 3)", 1, 7, "(5, 1, 3)");
test("(5, 1, 3)", 3, 7, "(1, 3, 2)");
test("(254, 2)", 254, 255, "(1, 253)");
}
fn mod_mul_fail_helper<T: PrimitiveUnsigned>() {
let v = UnsignedVector::<T> {
elements: vec![T::exact_from(7u8)],
};
assert_panic!(UnsignedVector::<T>::zero(0).mod_mul(T::ZERO, T::ZERO));
assert_panic!((&v).mod_mul(T::ONE, T::exact_from(7u8)));
assert_panic!((&v).mod_mul(T::exact_from(8u8), T::exact_from(8u8)));
assert_panic!({
let mut w = v.clone();
w.mod_mul_assign(T::ONE, T::exact_from(7u8));
});
}
#[test]
fn mod_mul_fail() {
apply_fn_to_unsigneds!(mod_mul_fail_helper);
}
fn mod_mul_properties_helper<T: PrimitiveUnsigned>() {
unsigned_vector_unsigned_unsigned_triple_gen_var_2::<T>().test_properties(|(v, c, m)| {
let w = (&v).mod_mul(c, m);
assert_eq!(v.clone().mod_mul(c, m), w);
let mut x = v.clone();
x.mod_mul_assign(c, m);
assert_eq!(x, w);
assert!(w.mod_is_reduced(&m));
assert_eq!(w.dimension(), v.dimension());
for (&x, &y) in v.elements.iter().zip(&w.elements) {
assert_eq!(y, x.mod_mul(c, m));
}
assert_eq!(
(&v).mod_mul(T::ZERO, m),
UnsignedVector::zero(v.dimension())
);
if m != T::ONE {
assert_eq!((&v).mod_mul(T::ONE, m), v);
}
assert_eq!((&v).mod_mul(c.mod_mul(c, m), m), (&w).mod_mul(c, m));
assert_eq!((&v).mod_add(&v, m).mod_mul(c, m), (&w).mod_add(&w, m));
});
}
#[test]
fn mod_mul_properties() {
apply_fn_to_unsigneds!(mod_mul_properties_helper);
}