mech_interpreter/stdlib/assign/op_assign/
add_assign.rs

1#[macro_use]
2use crate::stdlib::*;
3
4// Add Assign -----------------------------------------------------------------
5
6// We will mostly use the assign macros for this
7
8#[macro_export]
9macro_rules! impl_add_assign_match_arms {
10  ($fxn_name:ident,$macro_name:ident, $arg:expr) => {
11    paste!{
12      //VVVVVVVVV right there is where the assign macros come in.
13      [<impl_set_ $macro_name _match_arms>]!(
14        $fxn_name,
15        $arg,
16        U8, "U8";
17        U16, "U16";
18        U32, "U32";
19        U64, "U64";
20        U128, "U128";
21        I8, "I8";
22        I16, "I16";
23        I32, "I32";
24        I64, "I64";
25        U128, "U128";
26        F32, "F32"; 
27        F64, "F64" ;
28      )
29    }
30  }
31}
32
33macro_rules! impl_add_assign_fxn {
34  ($struct_name:ident, $matrix_shape:ident, $source_matrix_shape:ty, $op:ident, $ix:ty) => {
35    #[derive(Debug)]
36    struct $struct_name<T> {
37      source: Ref<$source_matrix_shape>,
38      ixes: Ref<DVector<$ix>>,
39      sink: Ref<$matrix_shape<T>>,
40    }
41    impl<T> MechFunction for $struct_name<T>
42    where
43      T: Copy + Debug + Clone + Sync + Send + 'static +
44      Add<Output = T> + AddAssign +
45      Zero + One +
46      PartialEq + PartialOrd,
47      Ref<$matrix_shape<T>>: ToValue
48    {
49      fn solve(&self) {
50        unsafe {
51          let ix_ptr = (*(self.ixes.as_ptr())).clone();
52          let mut sink_ptr = (&mut *(self.sink.as_ptr()));
53          let source_ptr = (*(self.source.as_ptr())).clone();
54          $op!(source_ptr,ix_ptr,sink_ptr);
55        }
56      }
57      fn out(&self) -> Value { self.sink.to_value() }
58      fn to_string(&self) -> String { format!("{:#?}", self) }
59    }};}
60
61// x = 1 ----------------------------------------------------------------------
62
63#[derive(Debug)]
64struct AddAssignVV<T> {
65  sink: Ref<T>,
66  source: Ref<T>,
67}
68impl<T> MechFunction for AddAssignVV<T> 
69where
70  T: Debug + Clone + Sync + Send + 'static +
71  Add<Output = T> + AddAssign +
72  PartialEq + PartialOrd,
73  Ref<T>: ToValue
74{
75  fn solve(&self) {
76    unsafe {
77      let mut sink_ptr = (&mut *(self.sink.as_ptr()));
78      let source_ptr = &(*(self.source.as_ptr()));
79      *sink_ptr += source_ptr.clone();
80    }
81  }
82  fn out(&self) -> Value { self.sink.to_value() }
83  fn to_string(&self) -> String { format!("{:#?}", self) }
84}
85
86#[derive(Debug)]
87struct AddAssignMDMD<T> {
88  sink: Ref<DMatrix<T>>,
89  source: Ref<DMatrix<T>>,
90}
91impl<T> MechFunction for AddAssignMDMD<T> 
92where
93  T: Debug + Clone + Sync + Send + 'static +
94  Add<Output = T> + AddAssign +
95  PartialEq + PartialOrd,
96  Ref<DMatrix<T>>: ToValue
97{
98  fn solve(&self) {
99    unsafe {
100      let mut sink_ptr = (&mut *(self.sink.as_ptr()));
101      let source_ptr = &(*(self.source.as_ptr()));
102      *sink_ptr += source_ptr;
103    }
104  }
105  fn out(&self) -> Value { self.sink.to_value() }
106  fn to_string(&self) -> String { format!("{:#?}", self) }
107}
108
109fn add_assign_value_fxn(sink: Value, source: Value) -> Result<Box<dyn MechFunction>, MechError> {
110  match (sink,source) {
111    (Value::U8(sink),Value::U8(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
112    (Value::U16(sink),Value::U16(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
113    (Value::U32(sink),Value::U32(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
114    (Value::U64(sink),Value::U64(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
115    (Value::U128(sink),Value::U128(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
116    (Value::I8(sink),Value::I8(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
117    (Value::I16(sink),Value::I16(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
118    (Value::I32(sink),Value::I32(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
119    (Value::I64(sink),Value::I64(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
120    (Value::I128(sink),Value::I128(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
121    (Value::F32(sink),Value::F32(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
122    (Value::F64(sink),Value::F64(source)) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
123    (Value::MatrixF64(Matrix::Matrix1(sink)),Value::MatrixF64(Matrix::Matrix1(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
124    (Value::MatrixF64(Matrix::Matrix2(sink)),Value::MatrixF64(Matrix::Matrix2(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
125    (Value::MatrixF64(Matrix::Matrix2x3(sink)),Value::MatrixF64(Matrix::Matrix2x3(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
126    (Value::MatrixF64(Matrix::Matrix3x2(sink)),Value::MatrixF64(Matrix::Matrix3x2(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
127    (Value::MatrixF64(Matrix::Matrix3(sink)),Value::MatrixF64(Matrix::Matrix3(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
128    (Value::MatrixF64(Matrix::Matrix4(sink)),Value::MatrixF64(Matrix::Matrix4(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
129    (Value::MatrixF64(Matrix::DMatrix(sink)),Value::MatrixF64(Matrix::DMatrix(source))) => Ok(Box::new(AddAssignMDMD{sink: sink.clone(), source: source.clone()})),
130    (Value::MatrixF64(Matrix::Vector2(sink)),Value::MatrixF64(Matrix::Vector2(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
131    (Value::MatrixF64(Matrix::Vector3(sink)),Value::MatrixF64(Matrix::Vector3(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
132    (Value::MatrixF64(Matrix::Vector4(sink)),Value::MatrixF64(Matrix::Vector4(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
133    (Value::MatrixF64(Matrix::DVector(sink)),Value::MatrixF64(Matrix::DVector(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
134    (Value::MatrixF64(Matrix::RowVector2(sink)),Value::MatrixF64(Matrix::RowVector2(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
135    (Value::MatrixF64(Matrix::RowVector3(sink)),Value::MatrixF64(Matrix::RowVector3(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
136    (Value::MatrixF64(Matrix::RowVector4(sink)),Value::MatrixF64(Matrix::RowVector4(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
137    (Value::MatrixF64(Matrix::RowDVector(sink)),Value::MatrixF64(Matrix::RowDVector(source))) => Ok(Box::new(AddAssignVV{sink: sink.clone(), source: source.clone()})),
138    x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
139  }
140}
141
142pub struct AddAssignValue {}
143impl NativeFunctionCompiler for AddAssignValue {
144  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
145    if arguments.len() <= 1 {
146      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
147    }
148    let sink = arguments[0].clone();
149    let source = arguments[1].clone();
150    match add_assign_value_fxn(sink.clone(),source.clone()) {
151      Ok(fxn) => Ok(fxn),
152      Err(x) => {
153        match (sink,source) {
154          (Value::MutableReference(sink),Value::MutableReference(source)) => { add_assign_value_fxn(sink.borrow().clone(),source.borrow().clone()) },
155          (sink,Value::MutableReference(source)) => { add_assign_value_fxn(sink.clone(),source.borrow().clone()) },
156          (Value::MutableReference(sink),source) => { add_assign_value_fxn(sink.borrow().clone(),source.clone()) },
157          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
158        }
159      }
160    }
161  }
162}
163
164// x[1..3] += 1 ----------------------------------------------------------------
165
166macro_rules! add_assign_1d_range {
167  ($source:expr, $ix:expr, $sink:expr) => {
168    unsafe { 
169      for i in 0..($ix).len() {
170        ($sink)[($ix)[i] - 1] += ($source);
171      }
172    }
173  };}
174
175macro_rules! add_assign_1d_range_b {
176  ($source:expr, $ix:expr, $sink:expr) => {
177    unsafe { 
178      for i in 0..($ix).len() {
179        if $ix[i] == true {
180          ($sink)[i] += ($source);
181        }
182      }
183    }
184  };}  
185
186macro_rules! add_assign_1d_range_vec {
187  ($source:expr, $ix:expr, $sink:expr) => {
188    unsafe { 
189      for i in 0..($ix).len() {
190        ($sink)[($ix)[i] - 1] += ($source)[i];
191      }
192    }
193  };}
194
195impl_add_assign_fxn!(AddAssign1DRRD,RowDVector,T,add_assign_1d_range,usize);
196impl_add_assign_fxn!(AddAssign1DRVD,DVector,T,add_assign_1d_range,usize);
197impl_add_assign_fxn!(AddAssign1DRMD,DMatrix,T,add_assign_1d_range,usize);
198impl_add_assign_fxn!(AddAssign1DRR4,RowVector4,T,add_assign_1d_range,usize);
199impl_add_assign_fxn!(AddAssign1DRR3,RowVector3,T,add_assign_1d_range,usize);
200impl_add_assign_fxn!(AddAssign1DRR2,RowVector2,T,add_assign_1d_range,usize);
201impl_add_assign_fxn!(AddAssign1DRV4,Vector4,T,add_assign_1d_range,usize);
202impl_add_assign_fxn!(AddAssign1DRV3,Vector3,T,add_assign_1d_range,usize);
203impl_add_assign_fxn!(AddAssign1DRV2,Vector2,T,add_assign_1d_range,usize);
204impl_add_assign_fxn!(AddAssign1DRM4,Matrix4,T,add_assign_1d_range,usize);
205impl_add_assign_fxn!(AddAssign1DRM3,Matrix3,T,add_assign_1d_range,usize);
206impl_add_assign_fxn!(AddAssign1DRM2,Matrix2,T,add_assign_1d_range,usize);
207impl_add_assign_fxn!(AddAssign1DRM1,Matrix1,T,add_assign_1d_range,usize);
208impl_add_assign_fxn!(AddAssign1DRM2x3,Matrix2x3,T,add_assign_1d_range,usize);
209impl_add_assign_fxn!(AddAssign1DRM3x2,Matrix3x2,T,add_assign_1d_range,usize);
210
211impl_add_assign_fxn!(AddAssign1DRRDB,RowDVector,T,add_assign_1d_range_b,bool);
212impl_add_assign_fxn!(AddAssign1DRVDB,DVector,T,add_assign_1d_range_b,bool);
213impl_add_assign_fxn!(AddAssign1DRMDB,DMatrix,T,add_assign_1d_range_b,bool);
214impl_add_assign_fxn!(AddAssign1DRR4B,RowVector4,T,add_assign_1d_range_b,bool);
215impl_add_assign_fxn!(AddAssign1DRR3B,RowVector3,T,add_assign_1d_range_b,bool);
216impl_add_assign_fxn!(AddAssign1DRR2B,RowVector2,T,add_assign_1d_range_b,bool);
217impl_add_assign_fxn!(AddAssign1DRV4B,Vector4,T,add_assign_1d_range_b,bool);
218impl_add_assign_fxn!(AddAssign1DRV3B,Vector3,T,add_assign_1d_range_b,bool);
219impl_add_assign_fxn!(AddAssign1DRV2B,Vector2,T,add_assign_1d_range_b,bool);
220impl_add_assign_fxn!(AddAssign1DRM4B,Matrix4,T,add_assign_1d_range_b,bool);
221impl_add_assign_fxn!(AddAssign1DRM3B,Matrix3,T,add_assign_1d_range_b,bool);
222impl_add_assign_fxn!(AddAssign1DRM2B,Matrix2,T,add_assign_1d_range_b,bool);
223impl_add_assign_fxn!(AddAssign1DRM1B,Matrix1,T,add_assign_1d_range_b,bool);
224impl_add_assign_fxn!(AddAssign1DRM2x3B,Matrix2x3,T,add_assign_1d_range_b,bool);
225impl_add_assign_fxn!(AddAssign1DRM3x2B,Matrix3x2,T,add_assign_1d_range_b,bool);
226
227impl_add_assign_fxn!(AddAssign1DRR4R4,RowVector4,RowVector4<T>,add_assign_1d_range_vec,usize);
228impl_add_assign_fxn!(AddAssign1DRR4R3,RowVector4,RowVector3<T>,add_assign_1d_range_vec,usize);
229impl_add_assign_fxn!(AddAssign1DRR4R2,RowVector4,RowVector2<T>,add_assign_1d_range_vec,usize);
230impl_add_assign_fxn!(AddAssign1DRV4V4,Vector4,Vector4<T>,add_assign_1d_range_vec,usize);
231impl_add_assign_fxn!(AddAssign1DRV4V3,Vector4,Vector3<T>,add_assign_1d_range_vec,usize);
232impl_add_assign_fxn!(AddAssign1DRV4V2,Vector4,Vector2<T>,add_assign_1d_range_vec,usize);
233
234impl_add_assign_fxn!(AddAssign1DRMDMD,DMatrix,DMatrix<T>,add_assign_1d_range_vec,usize);
235
236
237fn add_assign_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
238  impl_add_assign_match_arms!(AddAssign1DR, range, (sink, ixes.as_slice(), source))
239}
240
241pub struct AddAssignRange {}
242impl NativeFunctionCompiler for AddAssignRange {
243  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
244    if arguments.len() <= 1 {
245      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
246    }
247    let sink: Value = arguments[0].clone();
248    let source: Value = arguments[1].clone();
249    let ixes = arguments.clone().split_off(2);
250    match add_assign_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
251      Ok(fxn) => Ok(fxn),
252      Err(x) => {
253        match (sink,ixes,source) {
254          (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { add_assign_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
255          (sink,ixes,Value::MutableReference(source)) => { add_assign_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
256          (Value::MutableReference(sink),ixes,source) => { add_assign_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
257          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
258        }
259      }
260    }
261  }
262}
263
264// x[1..3,:] += 1 ------------------------------------------------------------------
265
266#[derive(Debug)]
267struct AddAssign2DRAMDMD<T> {
268  source: Ref<DMatrix<T>>,
269  ixes: Ref<DVector<usize>>,
270  sink: Ref<DMatrix<T>>,
271}
272impl<T> MechFunction for AddAssign2DRAMDMD<T>
273where
274  T: Copy + Debug + Clone + Sync + Send + 'static +
275  Add<Output = T> + AddAssign +
276  Zero + One +
277  PartialEq + PartialOrd,
278  Ref<DMatrix<T>>: ToValue
279{
280  fn solve(&self) {
281    unsafe {
282      let ix_ptr = &(*(self.ixes.as_ptr()));
283      let mut sink_ptr = (&mut *(self.sink.as_ptr()));
284      let source_ptr = &(*(self.source.as_ptr()));
285      for (i,rix) in (ix_ptr).iter().enumerate() {
286        let mut row = sink_ptr.row_mut(rix - 1);
287        row += (source_ptr).row(i);
288      }
289    }
290  }
291  fn out(&self) -> Value { self.sink.to_value() }
292  fn to_string(&self) -> String { format!("{:#?}", self) }
293}
294
295macro_rules! add_assign_2d_vector_all {
296  ($source:expr, $ix:expr, $sink:expr) => {
297      for cix in 0..($sink).ncols() {
298        for rix in &$ix {
299          ($sink).column_mut(cix)[rix - 1] += ($source);
300        }
301      }
302    };}
303
304macro_rules! add_assign_2d_vector_all_b {
305  ($source:expr, $ix:expr, $sink:expr) => {
306    for cix in 0..($sink).ncols() {
307      for rix in 0..$ix.len() {
308        if $ix[rix] == true {
309          ($sink).column_mut(cix)[rix] += ($source);
310        }
311      }
312    }
313  };} 
314
315
316macro_rules! add_assign_2d_vector_all_mat {
317  ($source:expr, $ix:expr, $sink:expr) => {
318    for (i,rix) in (&$ix).iter().enumerate() {
319      let mut row = ($sink).row_mut(rix - 1);
320      row += ($source).row(i);
321    }
322  };}
323
324macro_rules! add_assign_2d_vector_all_mat_b {
325  ($source:expr, $ix:expr, $sink:expr) => {
326    for (i,rix) in (&$ix).iter().enumerate() {
327      if *rix == true {
328        let mut row = ($sink).row_mut(i);
329        row += ($source).row(i);
330      }
331    }
332  };} 
333
334impl_add_assign_fxn!(AddAssign2DRAMD,DMatrix,T,add_assign_2d_vector_all,usize);
335impl_add_assign_fxn!(AddAssign2DRAM4,Matrix4,T,add_assign_2d_vector_all,usize);
336impl_add_assign_fxn!(AddAssign2DRAM3,Matrix3,T,add_assign_2d_vector_all,usize);
337impl_add_assign_fxn!(AddAssign2DRAM2,Matrix2,T,add_assign_2d_vector_all,usize);
338impl_add_assign_fxn!(AddAssign2DRAM1,Matrix1,T,add_assign_2d_vector_all,usize);
339impl_add_assign_fxn!(AddAssign2DRAM2x3,Matrix2x3,T,add_assign_2d_vector_all,usize);
340impl_add_assign_fxn!(AddAssign2DRAM3x2,Matrix3x2,T,add_assign_2d_vector_all,usize);
341
342//impl_add_assign_fxn!(AddAssign2DRAMDMD,DMatrix,DMatrix<T>,add_assign_2d_vector_all_mat,usize);
343
344impl_add_assign_fxn!(AddAssign2DRAMDM2,DMatrix,Matrix2<T>,add_assign_2d_vector_all_mat,usize);
345impl_add_assign_fxn!(AddAssign2DRAMDM2x3,DMatrix,Matrix2x3<T>,add_assign_2d_vector_all_mat,usize);
346impl_add_assign_fxn!(AddAssign2DRAMDM3,DMatrix,Matrix3<T>,add_assign_2d_vector_all_mat,usize);
347impl_add_assign_fxn!(AddAssign2DRAMDM3x2,DMatrix,Matrix3x2<T>,add_assign_2d_vector_all_mat,usize);
348impl_add_assign_fxn!(AddAssign2DRAMDM4,DMatrix,Matrix4<T>,add_assign_2d_vector_all_mat,usize);
349
350impl_add_assign_fxn!(AddAssign2DRAM2M2,Matrix2,Matrix2<T>,add_assign_2d_vector_all_mat,usize);
351impl_add_assign_fxn!(AddAssign2DRAM2M3x2,Matrix2,Matrix3x2<T>,add_assign_2d_vector_all_mat,usize);
352impl_add_assign_fxn!(AddAssign2DRAM2MD,Matrix2,DMatrix<T>,add_assign_2d_vector_all_mat,usize);
353
354impl_add_assign_fxn!(AddAssign2DRAM3M3,Matrix3,Matrix3<T>,add_assign_2d_vector_all_mat,usize);
355impl_add_assign_fxn!(AddAssign2DRAM3M2x3,Matrix3,Matrix2x3<T>,add_assign_2d_vector_all_mat,usize);
356impl_add_assign_fxn!(AddAssign2DRAM3MD,Matrix3,DMatrix<T>,add_assign_2d_vector_all_mat,usize);
357
358impl_add_assign_fxn!(AddAssign2DRAM3x2M3x2,Matrix3x2,Matrix3x2<T>,add_assign_2d_vector_all_mat,usize);
359impl_add_assign_fxn!(AddAssign2DRAM3x2M2,Matrix3x2,Matrix2<T>,add_assign_2d_vector_all_mat,usize);
360impl_add_assign_fxn!(AddAssign2DRAM3x2MD,Matrix3x2,DMatrix<T>,add_assign_2d_vector_all_mat,usize);
361
362impl_add_assign_fxn!(AddAssign2DRAM2x3M2x3,Matrix2x3,Matrix2x3<T>,add_assign_2d_vector_all_mat,usize);
363impl_add_assign_fxn!(AddAssign2DRAM2x3M3,Matrix2x3,Matrix3<T>,add_assign_2d_vector_all_mat,usize);
364impl_add_assign_fxn!(AddAssign2DRAM2x3MD,Matrix2x3,DMatrix<T>,add_assign_2d_vector_all_mat,usize);
365
366impl_add_assign_fxn!(AddAssign2DRAM4M4,Matrix4,Matrix4<T>,add_assign_2d_vector_all_mat,usize);
367impl_add_assign_fxn!(AddAssign2DRAM4MD,Matrix4,DMatrix<T>,add_assign_2d_vector_all_mat,usize);
368
369impl_add_assign_fxn!(AddAssign2DRAMDB,DMatrix,T,add_assign_2d_vector_all_b,bool);
370impl_add_assign_fxn!(AddAssign2DRAM4B,Matrix4,T,add_assign_2d_vector_all_b,bool);
371impl_add_assign_fxn!(AddAssign2DRAM3B,Matrix3,T,add_assign_2d_vector_all_b,bool);
372impl_add_assign_fxn!(AddAssign2DRAM2B,Matrix2,T,add_assign_2d_vector_all_b,bool);
373impl_add_assign_fxn!(AddAssign2DRAM1B,Matrix1,T,add_assign_2d_vector_all_b,bool);
374impl_add_assign_fxn!(AddAssign2DRAM2x3B,Matrix2x3,T,add_assign_2d_vector_all_b,bool);
375impl_add_assign_fxn!(AddAssign2DRAM3x2B,Matrix3x2,T,add_assign_2d_vector_all_b,bool);
376
377impl_add_assign_fxn!(AddAssign2DRAMDMDB,DMatrix,DMatrix<T>,add_assign_2d_vector_all_mat_b,bool);
378impl_add_assign_fxn!(AddAssign2DRAM2M2B,Matrix2,Matrix2<T>,add_assign_2d_vector_all_mat_b,bool);
379impl_add_assign_fxn!(AddAssign2DRAM3M3B,Matrix3,Matrix3<T>,add_assign_2d_vector_all_mat_b,bool);
380impl_add_assign_fxn!(AddAssign2DRAM4M4B,Matrix4,Matrix4<T>,add_assign_2d_vector_all_mat_b,bool);
381impl_add_assign_fxn!(AddAssign2DRAM3x2M3x2B,Matrix3x2,Matrix3x2<T>,add_assign_2d_vector_all_mat_b,bool);
382impl_add_assign_fxn!(AddAssign2DRAM2x3M2x3B,Matrix2x3,Matrix2x3<T>,add_assign_2d_vector_all_mat_b,bool);
383
384fn add_assign_vec_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
385  impl_add_assign_match_arms!(AddAssign2DRA, range_all, (sink, ixes.as_slice(), source))
386}
387
388pub struct AddAssignRangeAll {}
389impl NativeFunctionCompiler for AddAssignRangeAll {
390  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
391    if arguments.len() <= 1 {
392      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
393    }
394    let sink: Value = arguments[0].clone();
395    let source: Value = arguments[1].clone();
396    let ixes = arguments.clone().split_off(2);
397    match add_assign_vec_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
398      Ok(fxn) => Ok(fxn),
399      Err(_) => {
400        match (sink,ixes,source) {
401          (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { add_assign_vec_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
402          (sink,ixes,Value::MutableReference(source)) => { add_assign_vec_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
403          (Value::MutableReference(sink),ixes,source) => { add_assign_vec_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
404          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
405        }
406      }
407    }
408  }
409}