use crate::field::{Elem, FieldElem};
use crate::kernel::{FieldKernels, RawDispatch};
use super::{PreparedCoefficient, check_pair, check_width};
#[inline]
pub fn add_assign<F: FieldKernels>(dst: &mut [u8], src: &[u8]) {
check_pair::<F>("add_assign", "dst", dst.len(), "src", src.len());
F::add_assign(RawDispatch, dst, src);
}
#[inline]
pub fn add_assign_rows<F: FieldKernels>(dst: &mut [u8], row_len: usize, src: &[u8]) {
assert_ne!(row_len, 0, "add_assign_rows: row length must be nonzero");
check_width::<F>("add_assign_rows", row_len);
assert_eq!(
dst.len(),
src.len(),
"add_assign_rows: dst is {} bytes but src is {} bytes",
dst.len(),
src.len(),
);
assert_eq!(
dst.len() % row_len,
0,
"add_assign_rows: partial trailing row",
);
F::add_assign_rows(RawDispatch, dst, src, row_len);
}
#[inline]
pub fn sub_assign<F: FieldKernels>(dst: &mut [u8], src: &[u8]) {
check_pair::<F>("sub_assign", "dst", dst.len(), "src", src.len());
F::sub_assign(RawDispatch, dst, src);
}
#[inline]
pub fn sub_assign_rows<F: FieldKernels>(dst: &mut [u8], row_len: usize, src: &[u8]) {
assert_ne!(row_len, 0, "sub_assign_rows: row length must be nonzero");
check_width::<F>("sub_assign_rows", row_len);
assert_eq!(
dst.len(),
src.len(),
"sub_assign_rows: dst is {} bytes but src is {} bytes",
dst.len(),
src.len(),
);
assert_eq!(
dst.len() % row_len,
0,
"sub_assign_rows: partial trailing row",
);
F::sub_assign_rows(RawDispatch, dst, src, row_len);
}
#[inline]
pub fn mul_add<F: FieldKernels>(dst: &mut [u8], coeff: Elem<F>, src: &[u8]) {
check_pair::<F>("mul_add", "dst", dst.len(), "src", src.len());
if coeff.is_zero() {
return;
}
if coeff.is_one() {
F::add_assign(RawDispatch, dst, src);
return;
}
F::mul_add(RawDispatch, dst, &F::prepare(RawDispatch, coeff), src);
}
#[inline]
pub fn mul_add_with<F: FieldKernels>(
dst: &mut [u8],
coeff: &impl PreparedCoefficient<F>,
src: &[u8],
) {
check_pair::<F>("mul_add_with", "dst", dst.len(), "src", src.len());
let value = coeff.value();
if value.is_zero() {
return;
}
if value.is_one() {
F::add_assign(RawDispatch, dst, src);
return;
}
F::mul_add(RawDispatch, dst, coeff.repr(RawDispatch), src);
}
#[inline]
pub fn mul_into<F: FieldKernels>(dst: &mut [u8], coeff: Elem<F>, src: &[u8]) {
check_pair::<F>("mul_into", "dst", dst.len(), "src", src.len());
if coeff.is_zero() {
dst.fill(0);
return;
}
if coeff.is_one() {
dst.copy_from_slice(src);
return;
}
F::mul_into(RawDispatch, dst, &F::prepare(RawDispatch, coeff), src);
}
#[inline]
pub fn mul_into_with<F: FieldKernels>(
dst: &mut [u8],
coeff: &impl PreparedCoefficient<F>,
src: &[u8],
) {
check_pair::<F>("mul_into_with", "dst", dst.len(), "src", src.len());
let value = coeff.value();
if value.is_zero() {
dst.fill(0);
return;
}
if value.is_one() {
dst.copy_from_slice(src);
return;
}
F::mul_into(RawDispatch, dst, coeff.repr(RawDispatch), src);
}
#[inline]
pub fn mul_assign<F: FieldKernels>(dst: &mut [u8], coeff: Elem<F>) {
check_width::<F>("mul_assign", dst.len());
if coeff.is_one() {
return;
}
if coeff.is_zero() {
dst.fill(0);
return;
}
F::mul_assign(RawDispatch, dst, &F::prepare(RawDispatch, coeff));
}
#[inline]
pub fn mul_assign_with<F: FieldKernels>(dst: &mut [u8], coeff: &impl PreparedCoefficient<F>) {
check_width::<F>("mul_assign_with", dst.len());
let value = coeff.value();
if value.is_one() {
return;
}
if value.is_zero() {
dst.fill(0);
return;
}
F::mul_assign(RawDispatch, dst, coeff.repr(RawDispatch));
}
pub fn mul_elementwise<F: FieldKernels>(dst: &mut [u8], a: &[u8], b: &[u8]) {
check_pair::<F>("mul_elementwise", "dst", dst.len(), "a", a.len());
check_pair::<F>("mul_elementwise", "dst", dst.len(), "b", b.len());
F::mul_elementwise(RawDispatch, dst, a, b);
}
#[inline]
pub fn mul_elementwise_assign<F: FieldKernels>(dst: &mut [u8], src: &[u8]) {
check_pair::<F>("mul_elementwise_assign", "dst", dst.len(), "src", src.len());
F::mul_elementwise_assign(RawDispatch, dst, src);
}
#[inline]
pub fn add_assign_scalar<F: FieldKernels>(dst: &mut [u8], value: Elem<F>) {
check_width::<F>("add_assign_scalar", dst.len());
F::add_assign_scalar(RawDispatch, dst, &F::prepare(RawDispatch, value));
}
#[inline]
pub fn sub_assign_scalar<F: FieldKernels>(dst: &mut [u8], value: Elem<F>) {
check_width::<F>("sub_assign_scalar", dst.len());
F::sub_assign_scalar(RawDispatch, dst, &F::prepare(RawDispatch, value));
}