use { crate::{ core::{InnerViewPort, OuterViewPort}, projection::ProjectionHelper, sequence::SequenceView, vec::VecBuffer, }, std::sync::{Arc, RwLock}, }; fn posint_add( radix: usize, a: impl SequenceView, b: impl SequenceView, ) -> Vec { let mut carry = 0; let mut result = Vec::new(); for digit_idx in 0..std::cmp::max(a.len().unwrap_or(0), b.len().unwrap_or(0)) { let sum = a.get(&digit_idx).unwrap_or(0) + b.get(&digit_idx).unwrap_or(0) + carry; result.push(sum % radix); carry = if sum > radix { sum - radix } else { 0 }; } if carry > 0 { result.push(carry); } result } pub struct Add { radix: usize, a: Arc>, // PosInt, Little Endian b: Arc>, // PosInt, Little Endian c: VecBuffer, _proj_helper: ProjectionHelper, } impl Add { pub fn new( radix: usize, a: OuterViewPort>, b: OuterViewPort>, c: InnerViewPort>>, //> ) -> Arc> { let mut proj_helper = ProjectionHelper::new(c.0.update_hooks.clone()); let add = Arc::new(RwLock::new(Add { radix, a: proj_helper.new_sequence_arg(0, a, |s: &mut Self, _digit_idx| s.update()), b: proj_helper.new_sequence_arg(1, b, |s: &mut Self, _digit_idx| s.update()), c: VecBuffer::new(c), _proj_helper: proj_helper, })); add } fn update(&mut self) { self.c.clear(); for digit in posint_add(self.radix, self.a.clone(), self.b.clone()) { self.c.push(digit); } } }