use crate::fields::fp::FpVar;
use super::*;
mod saturating;
mod wrapping;
impl<const N: usize, T: PrimUInt, F: PrimeField> UInt<N, T, F> {
#[tracing::instrument(target = "gr1cs", skip(operands, adder))]
fn add_many_helper(
operands: &[Self],
adder: impl Fn(T, T) -> T,
) -> Result<(Vec<Boolean<F>>, Option<T>), SynthesisError> {
assert!(operands.len() >= 1);
let max_value_size = N as u32 + ark_std::log2(operands.len());
assert!(max_value_size <= F::MODULUS_BIT_SIZE);
if operands.len() == 1 {
return Ok((operands[0].bits.to_vec(), operands[0].value));
}
let mut value = Some(T::zero());
for op in operands {
value = value.and_then(|v| Some(adder(v, op.value?)));
}
if operands.is_constant() {
return Ok((Vec::new(), value));
}
let result = operands
.iter()
.map(|op| Boolean::le_bits_to_fp(&op.bits).unwrap())
.sum::<FpVar<_>>();
let (result, _) = result.to_bits_le_with_top_bits_zero(max_value_size as usize)?;
Ok((result, value))
}
}