use crate::integer_polynomial::arithmetic::coefficient::PolynomialCoefficient;
use crate::integer_vector::arithmetic::max_bits::vec_max_bits;
use crate::natural::InnerNatural::{Large, Small};
use crate::natural::Natural;
use crate::platform::Limb;
use malachite_base::num::arithmetic::traits::XXAddYYToZZ;
use malachite_base::num::basic::integers::PrimitiveInt;
use malachite_base::num::logic::traits::SignificantBits;
crate_test_fn! {vec_sum_max_bits<C: PolynomialCoefficient>(xs: &[C]) -> (u64, u64) {
let mut sum_hi: Limb = 0;
let mut sum_lo: Limb = 0;
let mut or: Limb = 0;
for x in xs {
match *x.unsigned_abs_ref() {
Natural(Small(small)) => {
(sum_hi, sum_lo) = Limb::xx_add_yy_to_zz(sum_hi, sum_lo, 0, small);
or |= small;
}
Natural(Large(_)) => {
let sum: Natural = xs.iter().map(PolynomialCoefficient::unsigned_abs_ref).sum();
return (sum.significant_bits(), vec_max_bits(xs).0);
}
}
}
let sum_bits = if sum_hi == 0 {
sum_lo.significant_bits()
} else {
Limb::WIDTH + sum_hi.significant_bits()
};
(sum_bits, or.significant_bits())
}}
crate_test_fn! {vec_sum_abs_significant_bits<C: PolynomialCoefficient>(xs: &[C]) -> u64 {
let mut sum_hi: Limb = 0;
let mut sum_lo: Limb = 0;
for x in xs {
match *x.unsigned_abs_ref() {
Natural(Small(small)) => {
(sum_hi, sum_lo) = Limb::xx_add_yy_to_zz(sum_hi, sum_lo, 0, small);
}
Natural(Large(_)) => {
return xs
.iter()
.map(PolynomialCoefficient::unsigned_abs_ref)
.sum::<Natural>()
.significant_bits();
}
}
}
if sum_hi == 0 {
sum_lo.significant_bits()
} else {
Limb::WIDTH + sum_hi.significant_bits()
}
}}