use crate::integer_polynomial::arithmetic::coefficient::PolynomialCoefficient;
use crate::integer_polynomial::arithmetic::vec::small_values;
use crate::platform::{SignedDoubleLimb, SignedLimb};
use alloc::vec;
use alloc::vec::Vec;
use malachite_base::num::basic::signeds::PrimitiveSigned;
use malachite_base::num::conversion::traits::ExactFrom;
pub(crate) fn square_truncated_to_out_tiny<
T: PrimitiveSigned + From<SignedLimb>,
C: PolynomialCoefficient + ExactFrom<T>,
>(
out: &mut [C],
xs: &[C],
) {
let n = out.len();
let xs: Vec<T> = small_values(&xs[..xs.len().min(n)]);
let mut res = vec![T::ZERO; n];
for (i, &x) in xs.iter().enumerate() {
if x != T::ZERO {
if i << 1 < n {
res[i << 1] += x * x;
}
let c = x << 1u64;
for (r, &y) in res.iter_mut().skip((i << 1) + 1).zip(&xs[i + 1..]) {
if y != T::ZERO {
*r += c * y;
}
}
}
}
for (o, r) in out.iter_mut().zip(res) {
*o = C::exact_from(r);
}
}
crate_test_fn! {
#[inline]
square_truncated_to_out_tiny_1<C: PolynomialCoefficient>(out: &mut [C], xs: &[C]) {
square_truncated_to_out_tiny::<SignedLimb, C>(out, xs);
}}
crate_test_fn! {
#[inline]
square_truncated_to_out_tiny_2<C: PolynomialCoefficient>(out: &mut [C], xs: &[C]) {
square_truncated_to_out_tiny::<SignedDoubleLimb, C>(out, xs);
}}