use { std::sync::{Arc, RwLock}, crate::{ core::{InnerViewPort, OuterViewPort}, sequence::{SequenceView, VecBuffer}, projection::ProjectionHelper } }; 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(); let add = Arc::new(RwLock::new( Add { radix, a: proj_helper.new_sequence_arg(a, |s: &mut Self, _digit_idx| s.update()), b: proj_helper.new_sequence_arg(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); } } }