mech_interpreter/stdlib/assign/
matrix.rs

1#[macro_use]
2use crate::stdlib::*;
3use std::marker::PhantomData;
4use std::fmt::Debug;
5use nalgebra::{
6  base::{Matrix as naMatrix, Storage, StorageMut},
7  Dim, Scalar,
8};
9
10// Set -----------------------------------------------------------------
11
12#[macro_export]
13macro_rules! impl_set_match_arms {
14  ($fxn_name:ident,$macro_name:ident, $arg:expr) => {
15    paste!{
16      [<impl_set_ $macro_name _match_arms>]!(
17        $fxn_name,
18        $arg,
19        Bool, "bool";
20        U8, "u8";
21        U16, "u16";
22        U32, "u32";
23        U64, "u64";
24        U128, "u128";
25        I8, "i8";
26        I16, "i16";
27        I32, "i32";
28        I64, "i64";
29        U128, "u128";
30        F32, "f32"; 
31        F64, "f64" ;
32        String, "string";
33        ComplexNumber, "complex";
34        RationalNumber, "rational";
35      )
36    }
37  }
38}
39
40#[macro_export]
41macro_rules! impl_set_all_fxn_s {
42  ($struct_name:ident, $op:ident, $ix:ty) => {
43    #[derive(Debug)]
44    pub struct $struct_name<T, MatA, IxVec> {
45      pub source: Ref<T>,
46      pub ixes: Ref<IxVec>,
47      pub sink: Ref<MatA>,
48      pub _marker: PhantomData<T>,
49    }
50    impl<T, R1, C1, S1, IxVec> MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
51    where
52      Ref<naMatrix<T, R1, C1, S1>>: ToValue,
53      T: Scalar + Clone + Debug + Sync + Send + 'static,
54      IxVec: AsRef<[$ix]> + Debug,
55      R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
56    {
57      fn solve(&self) {
58        unsafe {
59          let sink_ptr = &mut *self.sink.as_mut_ptr();
60          let source_ptr = &*self.source.as_ptr();
61          let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
62          $op!(source_ptr,ix_ptr,sink_ptr);
63        }
64      }
65      fn out(&self) -> Value {self.sink.to_value()}
66      fn to_string(&self) -> String {format!("{:#?}", self)}
67    }
68    #[cfg(feature = "compiler")]
69    impl<T, R1, C1, S1, IxVec> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec> {
70      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
71        todo!();
72      }
73    }};}
74
75#[macro_export]
76macro_rules! impl_set_all_fxn_v {
77  ($struct_name:ident, $op:ident, $ix:ty) => {
78    #[derive(Debug)]
79    pub struct $struct_name<T, MatA, MatB, IxVec> {
80      pub source: Ref<MatB>,
81      pub ixes: Ref<IxVec>,
82      pub sink: Ref<MatA>,
83      pub _marker: PhantomData<T>,
84    }
85
86    impl<T, R1, C1, S1, R2, C2, S2, IxVec>
87      MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
88    where
89      Ref<naMatrix<T, R1, C1, S1>>: ToValue,
90      T: Scalar + Clone + Debug + Sync + Send + 'static,
91      IxVec: AsRef<[$ix]> + Debug,
92      R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
93      R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
94    {
95      fn solve(&self) {
96        unsafe {
97          let sink_ptr = &mut *self.sink.as_mut_ptr();
98          let source_ptr = &*self.source.as_ptr();
99          let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
100          $op!(source_ptr,ix_ptr,sink_ptr);
101        }
102      }
103      fn out(&self) -> Value {self.sink.to_value()}
104      fn to_string(&self) -> String {format!("{:#?}", self)}
105    }
106    #[cfg(feature = "compiler")]
107    impl<T, R1, C1, S1, R2, C2, S2, IxVec> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec> {
108      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
109        todo!();
110      }
111    }};}
112
113// x[1] = 1 ------------------------------------------------------------------
114
115#[macro_export]
116macro_rules! set_1d_scalar {
117  ($source:expr, $ix:expr, $sink:expr) => {
118      ($sink)[$ix - 1] = ($source).clone();
119    };}
120
121#[macro_export]
122macro_rules! impl_set_fxn_s {
123  ($struct_name:ident, $op:ident, $ix:ty) => {
124    #[derive(Debug)]
125    pub struct $struct_name<T, MatA> {
126      pub source: Ref<T>,
127      pub ixes: Ref<$ix>,
128      pub sink: Ref<MatA>,
129      pub _marker: PhantomData<T>,
130    }
131    impl<T, R, C, S> MechFunctionImpl for $struct_name<T, naMatrix<T, R, C, S>>
132    where
133      Ref<naMatrix<T, R, C, S>>: ToValue,
134      T: Scalar + Clone + Debug + Sync + Send + 'static,
135      R: Dim,
136      C: Dim,
137      S: StorageMut<T, R, C> + Clone + Debug,
138    {
139      fn solve(&self) {
140        unsafe {
141          let mut sink_ptr = &mut *self.sink.as_mut_ptr();
142          let ix_val = (*self.ixes.as_ptr()).clone();
143          let source_val = (*self.source.as_ptr()).clone();
144          $op!(source_val, ix_val, sink_ptr);
145        }
146      }
147      fn out(&self) -> Value {self.sink.to_value()}
148      fn to_string(&self) -> String {format!("{:#?}", self)}
149    }
150    #[cfg(feature = "compiler")]
151    impl<T, R, C, S> MechFunctionCompiler for $struct_name<T, naMatrix<T, R, C, S>> {
152      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
153        todo!();
154      }
155    }};}
156
157impl_set_fxn_s!(Set1DS, set_1d_scalar, usize);
158
159#[derive(Debug)]
160pub struct Set1DSB<T, MatA> {
161  pub source: Ref<T>,
162  pub ixes: Ref<bool>,
163  pub sink: Ref<MatA>,
164  pub _marker: PhantomData<T>,
165}
166impl<T, R, C, S> MechFunctionImpl for Set1DSB<T, naMatrix<T, R, C, S>>
167where
168  Ref<naMatrix<T, R, C, S>>: ToValue,
169  T: Scalar + Clone + Debug + Sync + Send + 'static,
170  R: Dim,
171  C: Dim,
172  S: StorageMut<T, R, C> + Clone + Debug,
173{
174  fn solve(&self) {
175    unsafe {
176      let sink_ptr = &mut *self.sink.as_mut_ptr();
177      let ix_val = (*self.ixes.as_ptr()).clone();
178      let source_val = (*self.source.as_ptr()).clone();
179      if ix_val {
180        for iy in 0..sink_ptr.len() {
181          sink_ptr[iy] = source_val.clone();
182        }
183      }
184    }
185  }
186  fn out(&self) -> Value {self.sink.to_value()}
187  fn to_string(&self) -> String {format!("{:#?}", self)}
188}
189#[cfg(feature = "compiler")]
190impl<T, R, C, S> MechFunctionCompiler for Set1DSB<T, naMatrix<T, R, C, S>> {
191  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
192    todo!();
193  }
194}
195
196#[macro_export]
197macro_rules! impl_set_scalar_match_arms {
198  ($fxn_name:ident, $arg:expr, $($value_kind:ident,$value_string:tt);+ $(;)?) => {
199    paste!{
200      match $arg {
201        $(
202          #[cfg(all(feature = $value_string, feature = "row_vector4"))]
203          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
204          #[cfg(all(feature = $value_string, feature = "row_vector3"))]
205          (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)),[Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
206          #[cfg(all(feature = $value_string, feature = "row_vector2"))]
207          (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)),[Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
208          #[cfg(all(feature = $value_string, feature = "vector4"))]
209          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
210          #[cfg(all(feature = $value_string, feature = "vector3"))]
211          (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
212          #[cfg(all(feature = $value_string, feature = "vector2"))]
213          (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
214          #[cfg(all(feature = $value_string, feature = "MAtrix4"))]
215          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
216          #[cfg(all(feature = $value_string, feature = "matrix3"))]
217          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
218          #[cfg(all(feature = $value_string, feature = "matrix2"))]
219          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
220          #[cfg(all(feature = $value_string, feature = "MAtrix1"))]
221          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
222          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
223          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
224          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
225          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
226          #[cfg(all(feature = $value_string, feature = "matrixd"))]
227          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
228          #[cfg(all(feature = $value_string, feature = "row_vectord"))]
229          (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)),[Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
230          #[cfg(all(feature = $value_string, feature = "vectord"))]
231          (Value::[<Matrix $value_kind>](Matrix::DVector(sink)),   [Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new(Set1DS { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
232        
233          #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "bool"))]
234          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
235          #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "bool"))]
236          (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)),[Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
237          #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "bool"))]
238          (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)),[Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
239          #[cfg(all(feature = $value_string, feature = "vector4", feature = "bool"))]
240          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
241          #[cfg(all(feature = $value_string, feature = "vector3", feature = "bool"))]
242          (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
243          #[cfg(all(feature = $value_string, feature = "vector2", feature = "bool"))]
244          (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
245          #[cfg(all(feature = $value_string, feature = "MAtrix4", feature = "bool"))]
246          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
247          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
248          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
249          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
250          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
251          #[cfg(all(feature = $value_string, feature = "MAtrix1", feature = "bool"))]
252          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
253          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
254          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
255          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
256          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
257          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
258          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
259          #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "bool"))]
260          (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)),[Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
261          #[cfg(all(feature = $value_string, feature = "vectord", feature = "bool"))]
262          (Value::[<Matrix $value_kind>](Matrix::DVector(sink)),   [Value::Bool(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
263        )+
264        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
265      }
266    }
267  }
268}
269
270fn impl_set_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
271  impl_set_match_arms!(Set1DS, scalar, (sink, ixes.as_slice(), source))
272}
273
274pub struct MatrixSetScalar {}
275impl NativeFunctionCompiler for MatrixSetScalar {
276  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
277    if arguments.len() <= 1 {
278      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
279    }
280    let sink: Value = arguments[0].clone();
281    let source: Value = arguments[1].clone();
282    let ixes = arguments.clone().split_off(2);
283    match impl_set_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
284      Ok(fxn) => Ok(fxn),
285      Err(x) => {
286        match sink {
287          Value::MutableReference(sink) => { impl_set_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
288          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
289        }
290      }
291    }
292  }
293}
294
295// x[1..3] = 1 ----------------------------------------------------------------
296
297macro_rules! set_1d_range {
298  ($source:expr, $ix:expr, $sink:expr) => {
299    unsafe { 
300      for i in 0..($ix).len() {
301        ($sink)[($ix)[i] - 1] = ($source).clone();
302      }
303    }
304  };}
305
306macro_rules! set_1d_range_b {
307  ($source:expr, $ix:expr, $sink:expr) => {
308    unsafe { 
309      for i in 0..($ix).len() {
310        if $ix[i] == true {
311          ($sink)[i] = ($source).clone();
312        }
313      }
314    }
315  };}  
316
317macro_rules! set_1d_range_vec {
318  ($source:expr, $ix:expr, $sink:expr) => {
319    unsafe { 
320      for i in 0..($ix).len() {
321        ($sink)[($ix)[i] - 1] = ($source)[i].clone();
322      }
323    }
324  };}  
325
326macro_rules! set_1d_range_vec_b {
327  ($source:expr, $ix:expr, $sink:expr) => {
328    unsafe {
329      for i in 0..($ix).len() {
330        if $ix[i] == true {
331          ($sink)[i] = ($source)[i].clone();
332        }
333      }
334    }};}
335
336impl_set_all_fxn_s!(Set1DRS,set_1d_range,usize);
337impl_set_all_fxn_s!(Set1DRB,set_1d_range_b,bool);
338impl_set_all_fxn_v!(Set1DRV,set_1d_range_vec,usize);
339impl_set_all_fxn_v!(Set1DRVB,set_1d_range_vec_b,bool);
340
341fn impl_set_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
342  impl_set_match_arms!(Set1DR, range, (sink, ixes.as_slice(), source))
343}
344
345pub struct MatrixSetRange {}
346impl NativeFunctionCompiler for MatrixSetRange {
347  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
348    if arguments.len() <= 1 {
349      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
350    }
351    let sink: Value = arguments[0].clone();
352    let source: Value = arguments[1].clone();
353    let ixes = arguments.clone().split_off(2);
354    match impl_set_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
355      Ok(fxn) => Ok(fxn),
356      Err(x) => {
357        match (sink,source) {
358          (Value::MutableReference(sink),Value::MutableReference(source)) => { impl_set_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
359          (sink,Value::MutableReference(source)) => { impl_set_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
360          (Value::MutableReference(sink),source) => { impl_set_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
361          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
362        }
363      }
364    }
365  }
366}
367
368// x[:] = 1 ------------------------------------------------------------------
369use nalgebra::IsContiguous;
370#[derive(Debug)]
371pub struct Set1DA<T, Sink> {
372  pub source: Ref<T>,
373  pub sink: Ref<Sink>,
374  pub _marker: PhantomData<T>,
375}
376
377impl<T, R, C, S> MechFunctionImpl for Set1DA<T, naMatrix<T, R, C, S>>
378where
379  T: Debug + Clone + Sync + Send + PartialEq + 'static,
380  R: Dim,
381  C: Dim,
382  S: StorageMut<T, R, C> + Debug + IsContiguous,
383  Ref<naMatrix<T, R, C, S>>: ToValue,
384{
385  fn solve(&self) {
386    unsafe {
387      let sink = &mut *self.sink.as_mut_ptr();
388      let source_val = (*self.source.as_ptr()).clone();
389      let slice = sink.as_mut_slice();
390      for elem in slice.iter_mut() {
391        *elem = source_val.clone();
392      }
393    }
394  }
395  fn out(&self) -> Value {self.sink.to_value()}
396  fn to_string(&self) -> String {format!("{:#?}", self)}
397}
398#[cfg(feature = "compiler")]
399impl<T, R, C, S> MechFunctionCompiler for Set1DA<T, naMatrix<T, R, C, S>> { 
400  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
401    todo!();
402  }
403}
404
405#[macro_export]
406macro_rules! impl_set_all_match_arms {
407  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
408    paste!{
409      match $arg {
410        $(
411          #[cfg(all(feature = $value_string, feature = "row_vector4"))]
412          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
413          #[cfg(all(feature = $value_string, feature = "row_vector3"))]
414          (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
415          #[cfg(all(feature = $value_string, feature = "row_vector2"))]
416          (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
417          #[cfg(all(feature = $value_string, feature = "vector4"))]
418          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
419          #[cfg(all(feature = $value_string, feature = "vector3"))]
420          (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
421          #[cfg(all(feature = $value_string, feature = "vector2"))]
422          (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
423          #[cfg(all(feature = $value_string, feature = "matrix4"))]
424          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
425          #[cfg(all(feature = $value_string, feature = "matrix3"))]
426          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
427          #[cfg(all(feature = $value_string, feature = "matrix2"))]
428          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
429          #[cfg(all(feature = $value_string, feature = "matrix1"))]
430          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
431          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
432          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
433          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
434          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
435          #[cfg(all(feature = $value_string, feature = "matrixd"))]
436          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
437          #[cfg(all(feature = $value_string, feature = "row_vectord"))]
438          (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
439          #[cfg(all(feature = $value_string, feature = "vectord"))]
440          (Value::[<Matrix $value_kind>](Matrix::DVector(sink)), [Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), source: source.clone(), _marker: PhantomData::default() })),
441        )+
442        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
443      }
444    }
445  }
446}
447
448fn impl_set_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
449  impl_set_match_arms!(Set1DA, all, (sink, ixes.as_slice(), source))
450}
451
452pub struct MatrixSetAll {}
453impl NativeFunctionCompiler for MatrixSetAll {
454  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
455    if arguments.len() <= 1 {
456      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
457    }
458    let sink: Value = arguments[0].clone();
459    let source: Value = arguments[1].clone();
460    let ixes = arguments.clone().split_off(2);
461    match impl_set_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
462      Ok(fxn) => Ok(fxn),
463      Err(_) => {
464        match sink {
465          Value::MutableReference(sink) => { impl_set_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
466          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
467        }
468      }
469    }
470  }
471}
472
473// x[1,1] = 1 ----------------------------------------------------------------
474
475#[macro_export]
476macro_rules! impl_set_scalar_scalar_fxn {
477  ($struct_name:ident, $matrix_shape:ident, $op:tt) => {
478    #[derive(Debug)]
479    struct $struct_name<T> {
480      source: Ref<T>,
481      ixes: (Ref<usize>,Ref<usize>),
482      sink: Ref<$matrix_shape<T>>,
483    }
484    impl<T> MechFunctionImpl for $struct_name<T>
485    where
486      T: Debug + Clone + Sync + Send + PartialEq + 'static,
487      Ref<$matrix_shape<T>>: ToValue
488    {
489      fn solve(&self) {
490        unsafe {
491          let mut sink_ptr = (&mut *(self.sink.as_mut_ptr()));
492          let source_ptr = (*(self.source.as_ptr())).clone();
493          let (ix1,ix2) = &self.ixes;
494          let ix1_ptr = (*(ix1.as_ptr())).clone();
495          let ix2_ptr = (*(ix2.as_ptr())).clone();
496          $op!(sink_ptr,ix1_ptr,ix2_ptr,source_ptr);
497        }
498      }
499      fn out(&self) -> Value { self.sink.to_value() }
500      fn to_string(&self) -> String { format!("{:#?}", self) }
501    }
502    #[cfg(feature = "compiler")]
503    impl<T> MechFunctionCompiler for $struct_name<T> {
504      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
505        todo!();
506      }
507    }};}
508
509macro_rules! set_2d_scalar_scalar {
510  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
511      ($sink).column_mut($ix2 - 1)[$ix1 - 1] = ($source).clone();
512    };}
513
514impl_set_scalar_scalar_fxn!(Set2DSSMD,DMatrix,set_2d_scalar_scalar);
515impl_set_scalar_scalar_fxn!(Set2DSSM4,Matrix4,set_2d_scalar_scalar);
516impl_set_scalar_scalar_fxn!(Set2DSSM3,Matrix3,set_2d_scalar_scalar);
517impl_set_scalar_scalar_fxn!(Set2DSSM2,Matrix2,set_2d_scalar_scalar);
518impl_set_scalar_scalar_fxn!(Set2DSSM1,Matrix1,set_2d_scalar_scalar);
519impl_set_scalar_scalar_fxn!(Set2DSSM2x3,Matrix2x3,set_2d_scalar_scalar);
520impl_set_scalar_scalar_fxn!(Set2DSSM3x2,Matrix3x2,set_2d_scalar_scalar);
521
522#[macro_export]
523macro_rules! impl_set_scalar_scalar_match_arms {
524  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
525    paste!{
526      match $arg {
527        $(              
528          #[cfg(all(feature = $value_string, feature = "matrix4"))]
529          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M4>] { sink: sink.clone(),   ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
530          #[cfg(all(feature = $value_string, feature = "matrix3"))]
531          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3>] { sink: sink.clone(),   ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
532          #[cfg(all(feature = $value_string, feature = "matrix2"))]
533          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2>] { sink: sink.clone(),   ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
534          #[cfg(all(feature = $value_string, feature = "matrix1"))]
535          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M1>] { sink: sink.clone(),   ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
536          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
537          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2x3>] { sink: sink.clone(), ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
538          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
539          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3x2>] { sink: sink.clone(), ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
540          #[cfg(all(feature = $value_string, feature = "matrixd"))]
541          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::Index(ixx),Value::Index(ixy)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name MD>] { sink: sink.clone(),   ixes: (ixx.clone(),ixy.clone()), source: source.clone() })),
542        )+
543        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
544      }
545    }
546  }
547}
548
549fn impl_set_scalar_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
550  impl_set_match_arms!(Set2DSS, scalar_scalar, (sink, ixes.as_slice(), source))
551}
552
553pub struct MatrixSetScalarScalar {}
554impl NativeFunctionCompiler for MatrixSetScalarScalar {
555  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
556    if arguments.len() <= 1 {
557      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
558    }
559    let sink: Value = arguments[0].clone();
560    let source: Value = arguments[1].clone();
561    let ixes = arguments.clone().split_off(2);
562    match impl_set_scalar_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
563      Ok(fxn) => Ok(fxn),
564      Err(_) => {
565        match sink {
566          Value::MutableReference(sink) => { impl_set_scalar_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
567          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
568        }
569      }
570    }
571  }
572}
573
574// x[:,1] = 1 -----------------------------------------------------------------
575
576macro_rules! set_2d_all_scalar {
577  ($source:expr, $ix:expr, $sink:expr) => {
578      for i in 0..$sink.nrows() {
579        ($sink).column_mut($ix - 1)[i] = ($source).clone();
580      }
581    };}
582
583macro_rules! set_2d_all_vector {
584  ($source:expr, $ix:expr, $sink:expr) => {
585      for i in 0..$sink.nrows() {
586        ($sink).column_mut($ix - 1)[i] = ($source)[i].clone();
587      }
588    };}
589
590#[macro_export]
591macro_rules! impl_set_scalar_fxn_v {
592  ($struct_name:ident, $op:ident) => {
593    #[derive(Debug)]
594    pub struct $struct_name<T, MatA, MatB> {
595      pub source: Ref<MatB>,
596      pub ixes: Ref<usize>,
597      pub sink: Ref<MatA>,
598      pub _marker: PhantomData<T>,
599    }
600
601    impl<T, R1, C1, S1, R2, C2, S2>
602      MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>>
603    where
604      Ref<naMatrix<T, R1, C1, S1>>: ToValue,
605      T: Scalar + Clone + Debug + Sync + Send + 'static,
606      R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
607      R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
608    {
609      fn solve(&self) {
610        unsafe {
611          let sink_ptr = &mut *self.sink.as_mut_ptr();
612          let source_ptr = &*self.source.as_ptr();
613          let ix_ptr = &(*self.ixes.as_ptr());
614          $op!(source_ptr,ix_ptr,sink_ptr);
615        }
616      }
617      fn out(&self) -> Value {self.sink.to_value()}
618      fn to_string(&self) -> String {format!("{:#?}", self)}
619    }
620    #[cfg(feature = "compiler")] 
621    impl<T, R1, C1, S1, R2, C2, S2> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>> {
622      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
623        todo!();
624      }
625    }};}    
626
627impl_set_fxn_s!(Set2DASS, set_2d_all_scalar, usize);
628impl_set_scalar_fxn_v!(Set2DASV, set_2d_all_vector);
629
630#[macro_export]
631macro_rules! impl_set_all_scalar_match_arms {
632  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
633    paste!{
634      match $arg {
635        $(
636          #[cfg(all(feature = $value_string, feature = "matrix4"))]
637          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
638          #[cfg(all(feature = $value_string, feature = "matrix3"))]
639          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
640          #[cfg(all(feature = $value_string, feature = "matrix2"))]
641          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
642          #[cfg(all(feature = $value_string, feature = "matrix1"))]
643          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
644          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
645          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
646          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
647          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
648          #[cfg(all(feature = $value_string, feature = "matrixd"))]
649          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::IndexAll, Value::Index(ix)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
650          
651          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "vector2"))]
652          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)),   [Value::IndexAll, Value::Index(ix)], Value::[<Matrix $value_kind>](Matrix::Vector2(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
653          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "vector3"))]
654          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)),   [Value::IndexAll, Value::Index(ix)], Value::[<Matrix $value_kind>](Matrix::Vector3(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
655        )+
656        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
657      }
658    }
659  }
660}
661
662fn impl_set_all_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
663  impl_set_match_arms!(Set2DAS, all_scalar, (sink, ixes.as_slice(), source))
664}
665
666pub struct MatrixSetAllScalar {}
667impl NativeFunctionCompiler for MatrixSetAllScalar {
668  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
669    if arguments.len() <= 1 {
670      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
671    }
672    let sink: Value = arguments[0].clone();
673    let source: Value = arguments[1].clone();
674    let ixes = arguments.clone().split_off(2);
675    match impl_set_all_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
676      Ok(fxn) => Ok(fxn),
677      Err(x) => {
678        match sink {
679          Value::MutableReference(sink) => { impl_set_all_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
680          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}", x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
681        }
682      }
683    }
684  }
685}
686
687// x[1,:] = 1 -----------------------------------------------------------------
688
689macro_rules! set_2d_scalar_all {
690  ($sink:expr, $ix:expr, $source:expr) => {
691      for i in 0..($sink).ncols() {
692        ($sink).row_mut($ix - 1)[i] = ($source).clone();
693      }
694    };}
695
696#[macro_export]
697macro_rules! impl_set_scalar_all_fxn {
698  ($struct_name:ident, $matrix_shape:ident, $op:tt) => {
699    #[derive(Debug)]
700    struct $struct_name<T> {
701      source: Ref<T>,
702      ix: Ref<usize>,
703      sink: Ref<$matrix_shape<T>>,
704    }
705    impl<T> MechFunctionImpl for $struct_name<T>
706    where
707      T: Debug + Clone + Sync + Send + PartialEq + 'static,
708      Ref<$matrix_shape<T>>: ToValue
709    {
710      fn solve(&self) {
711        unsafe {
712          let ix_ptr = (*(self.ix.as_ptr())).clone();
713          let mut sink_ptr = (&mut *(self.sink.as_mut_ptr()));
714          let source_ptr = (*(self.source.as_ptr())).clone();
715          $op!(sink_ptr,ix_ptr,source_ptr);
716        }
717      }
718      fn out(&self) -> Value { self.sink.to_value() }
719      fn to_string(&self) -> String { format!("{:#?}", self) }
720    }
721    #[cfg(feature = "compiler")]
722    impl<T> MechFunctionCompiler for $struct_name<T> {
723      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
724        todo!();
725      }
726    }};}
727
728impl_set_scalar_all_fxn!(Set2DSAMD,DMatrix, set_2d_scalar_all);
729impl_set_scalar_all_fxn!(Set2DSAM4,Matrix4, set_2d_scalar_all);
730impl_set_scalar_all_fxn!(Set2DSAM3,Matrix3, set_2d_scalar_all);
731impl_set_scalar_all_fxn!(Set2DSAM2,Matrix2, set_2d_scalar_all);
732impl_set_scalar_all_fxn!(Set2DSAM1,Matrix1, set_2d_scalar_all);
733impl_set_scalar_all_fxn!(Set2DSAM2x3,Matrix2x3, set_2d_scalar_all);
734impl_set_scalar_all_fxn!(Set2DSAM3x2,Matrix3x2, set_2d_scalar_all);
735
736#[macro_export]
737macro_rules! impl_set_scalar_all_match_arms {
738  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
739    paste!{
740      match $arg {
741        $(
742          #[cfg(all(feature = $value_string, feature = "matrix4"))]
743          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M4>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
744          #[cfg(all(feature = $value_string, feature = "matrix3"))]
745          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
746          #[cfg(all(feature = $value_string, feature = "matrix2"))]
747          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
748          #[cfg(all(feature = $value_string, feature = "matrix1"))]
749          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M1>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
750          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
751          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2x3>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
752          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
753          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3x2>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
754          #[cfg(all(feature = $value_string, feature = "matrixd"))]
755          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::Index(ix), Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name MD>] { sink: sink.clone(), ix: ix.clone(), source: source.clone() })),
756        )+
757        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
758      }
759    }
760  }
761}
762
763fn impl_set_scalar_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
764  impl_set_match_arms!(Set2DSA, scalar_all, (sink, ixes.as_slice(), source))
765}
766
767pub struct MatrixSetScalarAll {}
768impl NativeFunctionCompiler for MatrixSetScalarAll {
769  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
770    if arguments.len() <= 1 {
771      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
772    }
773    let sink: Value = arguments[0].clone();
774    let source: Value = arguments[1].clone();
775    let ixes = arguments.clone().split_off(2);
776    match impl_set_scalar_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
777      Ok(fxn) => Ok(fxn),
778      Err(_) => {
779        match sink {
780          Value::MutableReference(sink) => { impl_set_scalar_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
781          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
782        }
783      }
784    }
785  }
786}
787
788// x[1..3,1] = 1 ------------------------------------------------------------------
789
790macro_rules! set_2d_vector_scalar {
791  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
792      for rix in &$ix1 {
793        ($sink).row_mut(rix - 1)[$ix2 - 1] = ($source).clone();
794      }
795    };}
796
797macro_rules! set_2d_vector_scalar_b {
798  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
799    unsafe { 
800      for rix in 0..($ix1).len() {
801        if $ix1[rix] == true {
802          ($sink).row_mut(rix)[$ix2 - 1] = ($source).clone();
803        }
804      }
805    }
806  };}  
807
808#[macro_export]
809macro_rules! impl_set_range_scalar_fxn {
810  ($struct_name:ident, $matrix_shape:ident, $op:tt, $ix_type:ty) => {
811    #[derive(Debug)]
812    struct $struct_name<T> {
813      source: Ref<T>,
814      ixes: (Ref<DVector<$ix_type>>,Ref<usize>),
815      sink: Ref<$matrix_shape<T>>,
816    }
817    impl<T> MechFunctionImpl for $struct_name<T>
818    where
819      T: Debug + Clone + Sync + Send + PartialEq + 'static,
820      Ref<$matrix_shape<T>>: ToValue
821    {
822      fn solve(&self) {
823        unsafe { 
824          let mut sink_ptr = (&mut *(self.sink.as_mut_ptr()));
825          let source_ptr = (*(self.source.as_ptr())).clone();
826          let (ix1,ix2) = &self.ixes;
827          let ix1_ptr = (*(ix1.as_ptr())).clone();
828          let ix2_ptr = (*(ix2.as_ptr())).clone();
829          $op!(sink_ptr,ix1_ptr,ix2_ptr,source_ptr);
830        }
831      }
832      fn out(&self) -> Value { self.sink.to_value() }
833      fn to_string(&self) -> String { format!("{:#?}", self) }
834    }
835    #[cfg(feature = "compiler")]
836    impl<T> MechFunctionCompiler for $struct_name<T> {
837      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
838        todo!();
839      }
840    }};}
841
842impl_set_range_scalar_fxn!(Set2DRSMD,DMatrix, set_2d_vector_scalar, usize);
843impl_set_range_scalar_fxn!(Set2DRSM4,Matrix4, set_2d_vector_scalar, usize);
844impl_set_range_scalar_fxn!(Set2DRSM3,Matrix3, set_2d_vector_scalar, usize);
845impl_set_range_scalar_fxn!(Set2DRSM2,Matrix2, set_2d_vector_scalar, usize);
846impl_set_range_scalar_fxn!(Set2DRSM1,Matrix1, set_2d_vector_scalar, usize);
847impl_set_range_scalar_fxn!(Set2DRSM2x3,Matrix2x3, set_2d_vector_scalar, usize);
848impl_set_range_scalar_fxn!(Set2DRSM3x2,Matrix3x2, set_2d_vector_scalar, usize);
849
850impl_set_range_scalar_fxn!(Set2DRSMDB,DMatrix, set_2d_vector_scalar_b, bool);
851impl_set_range_scalar_fxn!(Set2DRSM4B,Matrix4, set_2d_vector_scalar_b, bool);
852impl_set_range_scalar_fxn!(Set2DRSM3B,Matrix3, set_2d_vector_scalar_b, bool);
853impl_set_range_scalar_fxn!(Set2DRSM2B,Matrix2, set_2d_vector_scalar_b, bool);
854impl_set_range_scalar_fxn!(Set2DRSM1B,Matrix1, set_2d_vector_scalar_b, bool);
855impl_set_range_scalar_fxn!(Set2DRSM2x3B,Matrix2x3, set_2d_vector_scalar_b, bool);
856impl_set_range_scalar_fxn!(Set2DRSM3x2B,Matrix3x2, set_2d_vector_scalar_b, bool);
857
858#[macro_export]
859macro_rules! impl_set_range_scalar_match_arms {
860  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
861    paste!{
862      match $arg {
863        $(
864          #[cfg(all(feature = $value_string, feature = "matrix4"))]
865          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M4>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
866          #[cfg(all(feature = $value_string, feature = "matrix3"))]
867          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
868          #[cfg(all(feature = $value_string, feature = "matrix2"))]
869          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
870          #[cfg(all(feature = $value_string, feature = "matrix1"))]
871          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M1>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
872          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
873          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2x3>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
874          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
875          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3x2>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
876          #[cfg(all(feature = $value_string, feature = "matrixd"))]
877          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::MatrixIndex(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name MD>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
878          
879          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
880          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M4B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
881          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
882          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
883          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
884          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
885          #[cfg(all(feature = $value_string, feature = "matrix1", feature = "bool"))]
886          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M1B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
887          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
888          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M2x3B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
889          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
890          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name M3x2B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
891          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
892          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::MatrixBool(Matrix::DVector(ix1)),Value::Index(ix2)], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name MDB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone() })),
893        
894        )+
895        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
896      }
897    }
898  }
899}
900
901fn impl_set_range_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
902  impl_set_match_arms!(Set2DRS, range_scalar, (sink, ixes.as_slice(), source))
903}
904
905pub struct MatrixSetRangeScalar {}
906impl NativeFunctionCompiler for MatrixSetRangeScalar {
907  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
908    if arguments.len() <= 1 {
909      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
910    }
911    let sink: Value = arguments[0].clone();
912    let source: Value = arguments[1].clone();
913    let ixes = arguments.clone().split_off(2);
914    match impl_set_range_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
915      Ok(fxn) => Ok(fxn),
916      Err(_) => {
917        match sink {
918          Value::MutableReference(sink) => { impl_set_range_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
919          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
920        }
921      }
922    }
923  }
924}
925
926// x[1,1..3] = 1 ------------------------------------------------------------------
927
928#[derive(Debug)]
929pub struct Set2DSR<T, MatA, IxVec> {
930  pub source: Ref<T>,
931  pub ixes: (Ref<usize>, Ref<IxVec>),
932  pub sink: Ref<MatA>,
933  pub _marker: PhantomData<T>,
934}
935
936impl<T, R, C, S, IxVec> MechFunctionImpl for Set2DSR<T, na::Matrix<T, R, C, S>, IxVec>
937where
938  Ref<na::Matrix<T, R, C, S>>: ToValue,
939  T: Scalar + Clone + Debug + Sync + Send + 'static,
940  R: nalgebra::Dim,
941  C: nalgebra::Dim,
942  S: nalgebra::StorageMut<T, R, C> + Clone + Debug,
943  IxVec: AsRef<[usize]> + Debug,
944{
945  fn solve(&self) {
946    unsafe {
947      let sink = &mut *self.sink.as_mut_ptr();
948      let source = &*self.source.as_ptr();
949      let ix1 = *self.ixes.0.as_ptr();
950      let ix2 = (*self.ixes.1.as_ptr()).as_ref();
951
952      for &rix in ix2 {
953        sink.column_mut(rix - 1)[ix1 - 1] = source.clone();
954      }
955    }
956  }
957  fn out(&self) -> Value {self.sink.to_value()}
958  fn to_string(&self) -> String {format!("{:#?}", self)}
959}
960#[cfg(feature = "compiler")]
961impl<T, R, C, S, IxVec> MechFunctionCompiler for Set2DSR<T, na::Matrix<T, R, C, S>, IxVec> {
962  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
963    todo!();
964  }
965}
966
967#[derive(Debug)]
968pub struct Set2DSRB<T, MatA, IxVec> {
969  pub source: Ref<T>,
970  pub ixes: (Ref<usize>, Ref<IxVec>),
971  pub sink: Ref<MatA>,
972  pub _marker: PhantomData<T>,
973}
974
975impl<T, R, C, S, IxVec> MechFunctionImpl for Set2DSRB<T, na::Matrix<T, R, C, S>, IxVec>
976where
977  Ref<na::Matrix<T, R, C, S>>: ToValue,
978  T: Scalar + Clone + Debug + Sync + Send + 'static,
979  R: nalgebra::Dim,
980  C: nalgebra::Dim,
981  S: nalgebra::StorageMut<T, R, C> + Clone + Debug,
982  IxVec: AsRef<[bool]> + Debug,
983{
984  fn solve(&self) {
985    unsafe {
986      let sink = &mut *self.sink.as_mut_ptr();
987      let source = &*self.source.as_ptr();
988      let ix1 = *self.ixes.0.as_ptr();
989      let ix2 = (*self.ixes.1.as_ptr()).as_ref();
990      for i in 0..ix2.len() {
991        if ix2[i] {
992          sink.row_mut(i)[ix1 - 1] = source.clone();
993        }
994      }
995    }
996  }
997  fn out(&self) -> Value {self.sink.to_value()}
998  fn to_string(&self) -> String {format!("{:#?}", self)}
999}
1000#[cfg(feature = "compiler")]
1001impl<T, R, C, S, IxVec> MechFunctionCompiler for Set2DSRB<T, na::Matrix<T, R, C, S>, IxVec> {
1002  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1003    todo!();
1004  }
1005}
1006
1007#[macro_export]
1008macro_rules! impl_set_scalar_range_match_arms {
1009  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
1010    paste!{
1011      match $arg {
1012        $(
1013          #[cfg(all(feature = $value_string, feature = "matrix4"))]
1014          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1015          #[cfg(all(feature = $value_string, feature = "matrix3"))]
1016          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1017          #[cfg(all(feature = $value_string, feature = "matrix2"))]
1018          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1019          #[cfg(all(feature = $value_string, feature = "matrix1"))]
1020          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1021          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1022          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1023          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1024          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1025          #[cfg(all(feature = $value_string, feature = "matrixd"))]
1026          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::Index(ix1),Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1027        
1028          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
1029          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1030          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
1031          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1032          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
1033          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1034          #[cfg(all(feature = $value_string, feature = "matrix1", feature = "bool"))]
1035          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1036          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
1037          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1038          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
1039          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1040          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
1041          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::Index(ix1),Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1042        )+
1043        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
1044      }
1045    }
1046  }
1047}
1048
1049fn impl_set_scalar_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
1050  impl_set_match_arms!(Set2DSR, scalar_range, (sink, ixes.as_slice(), source))
1051}
1052
1053pub struct MatrixSetScalarRange {}
1054impl NativeFunctionCompiler for MatrixSetScalarRange {
1055  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1056    if arguments.len() <= 1 {
1057      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
1058    }
1059    let sink: Value = arguments[0].clone();
1060    let source: Value = arguments[1].clone();
1061    let ixes = arguments.clone().split_off(2);
1062    match impl_set_scalar_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
1063      Ok(fxn) => Ok(fxn),
1064      Err(_) => {
1065        match sink {
1066          Value::MutableReference(sink) => { impl_set_scalar_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
1067          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
1068        }
1069      }
1070    }
1071  }
1072}
1073
1074// x[1..3,1..3] = 1 ------------------------------------------------------------------
1075
1076#[derive(Debug)]
1077pub struct Set2DRRS<T, MatA, IxVec1, IxVec2> {
1078  pub source: Ref<T>,
1079  pub ixes: (Ref<IxVec1>, Ref<IxVec2>),
1080  pub sink: Ref<MatA>,
1081  pub _marker: PhantomData<T>,
1082}
1083
1084impl<T, R, C, S, IxVec1, IxVec2> MechFunctionImpl for Set2DRRS<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
1085where
1086  Ref<na::Matrix<T, R, C, S>>: ToValue,
1087  T: Scalar + Clone + Debug + Sync + Send + 'static,
1088  R: nalgebra::Dim,
1089  C: nalgebra::Dim,
1090  S: nalgebra::StorageMut<T, R, C> + Clone + Debug,
1091  IxVec1: AsRef<[usize]> + Debug,
1092  IxVec2: AsRef<[usize]> + Debug,
1093{
1094  fn solve(&self) {
1095    unsafe {
1096      let sink = &mut *self.sink.as_mut_ptr();
1097      let source = &*self.source.as_ptr();
1098      let ix1 = (*self.ixes.0.as_ptr()).as_ref();
1099      let ix2 = (*self.ixes.1.as_ptr()).as_ref();
1100
1101      for &cix in ix1 {
1102        for &rix in ix2 {
1103          sink.column_mut(cix - 1)[rix - 1] = source.clone();
1104        }
1105      }
1106    }
1107  }
1108  fn out(&self) -> Value {self.sink.to_value()}
1109  fn to_string(&self) -> String {format!("{:#?}", self)}
1110}
1111#[cfg(feature = "compiler")]
1112impl<T, R, C, S, IxVec1, IxVec2> MechFunctionCompiler for Set2DRRS<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2> {
1113  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1114    todo!();
1115  }
1116}
1117
1118#[derive(Debug)]
1119pub struct Set2DRRSB<T, MatA, IxVec1, IxVec2> {
1120  pub source: Ref<T>,
1121  pub ixes: (Ref<IxVec1>, Ref<IxVec2>),
1122  pub sink: Ref<MatA>,
1123  pub _marker: PhantomData<T>,
1124}
1125
1126impl<T, R, C, S, IxVec1, IxVec2> MechFunctionImpl for Set2DRRSB<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
1127where
1128  Ref<na::Matrix<T, R, C, S>>: ToValue,
1129  T: Scalar + Clone + Debug + Sync + Send + 'static,
1130  R: nalgebra::Dim,
1131  C: nalgebra::Dim,
1132  S: nalgebra::StorageMut<T, R, C> + Clone + Debug,
1133  IxVec1: AsRef<[bool]> + Debug,
1134  IxVec2: AsRef<[bool]> + Debug,
1135{
1136  fn solve(&self) {
1137    unsafe {
1138      let sink = &mut *self.sink.as_mut_ptr();
1139      let source = &*self.source.as_ptr();
1140      let ix1 = (*self.ixes.0.as_ptr()).as_ref();
1141      let ix2 = (*self.ixes.1.as_ptr()).as_ref();
1142
1143      for cix in 0..ix1.len() {
1144        for rix in 0..ix2.len() {
1145          if ix1[cix] && ix2[rix] {
1146            sink.row_mut(rix)[cix] = source.clone();
1147          }
1148        }
1149      }
1150    }
1151  }
1152  fn out(&self) -> Value {self.sink.to_value()}
1153  fn to_string(&self) -> String {format!("{:#?}", self)}
1154}
1155#[cfg(feature = "compiler")]
1156impl<T, R, C, S, IxVec1, IxVec2> MechFunctionCompiler for Set2DRRSB<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2> {
1157  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1158    todo!();
1159  }
1160}
1161
1162#[macro_export]
1163macro_rules! impl_set_range_range_match_arms {
1164  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
1165    paste! {
1166      match $arg {
1167        $(
1168          #[cfg(all(feature = $value_string, feature = "matrix4"))]
1169          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1170          #[cfg(all(feature = $value_string, feature = "matrix3"))]
1171          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1172          #[cfg(all(feature = $value_string, feature = "matrix2"))]
1173          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1174          #[cfg(all(feature = $value_string, feature = "matrix1"))]
1175          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1176          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1177          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1178          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1179          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1180          #[cfg(all(feature = $value_string, feature = "matrixd"))]
1181          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1182
1183          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
1184          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1185          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
1186          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1187          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
1188          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1189          #[cfg(all(feature = $value_string, feature = "matrix1", feature = "bool"))]
1190          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1191          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
1192          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1193          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
1194          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1195          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
1196          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: (ix1.clone(), ix2.clone()), source: source.clone(), _marker: PhantomData::default() })),
1197        )+
1198        x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}", x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
1199      }
1200    }
1201  }
1202}
1203
1204fn impl_set_range_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
1205  impl_set_match_arms!(Set2DRR, range_range, (sink, ixes.as_slice(), source))
1206}
1207
1208pub struct MatrixSetRangeRange {}
1209impl NativeFunctionCompiler for MatrixSetRangeRange {
1210  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1211    if arguments.len() <= 1 {
1212      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
1213    }
1214    let sink: Value = arguments[0].clone();
1215    let source: Value = arguments[1].clone();
1216    let ixes = arguments.clone().split_off(2);
1217    match impl_set_range_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
1218      Ok(fxn) => Ok(fxn),
1219      Err(_) => {
1220        match sink {
1221          Value::MutableReference(sink) => { impl_set_range_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
1222          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
1223        }
1224      }
1225    }
1226  }
1227}
1228
1229// x[:,1..3] = 1 ------------------------------------------------------------------
1230
1231macro_rules! set_2d_all_vector {
1232  ($source:expr, $ix:expr, $sink:expr) => {
1233      for cix in $ix.iter() {
1234        for rix in 0..($sink).nrows() {
1235          ($sink).column_mut(cix - 1)[rix] = ($source).clone();
1236        }
1237      }
1238    };}
1239
1240macro_rules! set_2d_all_vector_b {
1241  ($source:expr, $ix:expr, $sink:expr) => {
1242      for cix in 0..$ix.len() {
1243        for rix in 0..($sink).nrows() {
1244          if $ix[cix] == true {
1245            ($sink).column_mut(cix)[rix] = ($source).clone();
1246          }
1247        }
1248      }
1249    };}    
1250
1251impl_set_all_fxn_s!(Set2DAR,set_2d_all_vector,usize);
1252impl_set_all_fxn_s!(Set2DARB,set_2d_all_vector_b,bool);
1253
1254#[macro_export]
1255macro_rules! impl_set_all_range_match_arms {
1256  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
1257    paste!{
1258      match $arg {
1259        $(
1260          #[cfg(all(feature = $value_string, feature = "matrix4"))]
1261          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1262          #[cfg(all(feature = $value_string, feature = "matrix3"))]
1263          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1264          #[cfg(all(feature = $value_string, feature = "matrix2"))]
1265          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1266          #[cfg(all(feature = $value_string, feature = "matrix1"))]
1267          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1268          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1269          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1270          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1271          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1272          #[cfg(all(feature = $value_string, feature = "matrixd"))]
1273          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::IndexAll,Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new($fxn_name { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1274
1275          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
1276          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1277          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
1278          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1279          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
1280          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1281          #[cfg(all(feature = $value_string, feature = "matrix1", feature = "bool"))]
1282          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1283          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
1284          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1285          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
1286          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1287          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
1288          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::IndexAll,Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes:   ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
1289        )+
1290        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
1291      }
1292    }
1293  }
1294}
1295
1296fn impl_set_all_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
1297  impl_set_match_arms!(Set2DAR, all_range, (sink, ixes.as_slice(), source))
1298}
1299
1300pub struct MatrixSetAllRange {}
1301impl NativeFunctionCompiler for MatrixSetAllRange {
1302  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1303    if arguments.len() <= 1 {
1304      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
1305    }
1306    let sink: Value = arguments[0].clone();
1307    let source: Value = arguments[1].clone();
1308    let ixes = arguments.clone().split_off(2);
1309    match impl_set_all_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
1310      Ok(fxn) => Ok(fxn),
1311      Err(_) => {
1312        match sink {
1313          Value::MutableReference(sink) => { impl_set_all_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
1314          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
1315        }
1316      }
1317    }
1318  }
1319}
1320
1321// x[1..3,:] = 1 ------------------------------------------------------------------
1322
1323
1324macro_rules! set_2d_vector_all {
1325  ($source:expr, $ix:expr, $sink:expr) => {
1326      for cix in 0..($sink).ncols() {
1327        for rix in $ix.iter() {
1328          ($sink).column_mut(cix)[rix - 1] = ($source).clone();
1329        }
1330      }
1331    };}
1332
1333macro_rules! set_2d_vector_all_b {
1334  ($source:expr, $ix:expr, $sink:expr) => {
1335    for cix in 0..($sink).ncols() {
1336      for rix in 0..$ix.len() {
1337        if $ix[rix] == true {
1338          ($sink).column_mut(cix)[rix - 1] = ($source).clone();
1339        }
1340      }
1341    }
1342  };} 
1343
1344macro_rules! set_2d_vector_all_mat {
1345  ($source:expr, $ix:expr, $sink:expr) => {
1346    for (i, &rix) in $ix.iter().enumerate() {
1347      let mut sink_row = $sink.row_mut(rix - 1);
1348      let src_row = $source.row(i);
1349      for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
1350        *dst = src.clone();
1351      }
1352    }
1353  };}
1354  
1355macro_rules! set_2d_vector_all_mat_b {
1356  ($source:expr, $ix:expr, $sink:expr) => {
1357    for (i, rix) in (&$ix).iter().enumerate() {
1358      if *rix == true {
1359        let mut row = ($sink).row_mut(i);
1360        let src_row = ($source).row(i);
1361        for (dst, src) in row.iter_mut().zip(src_row.iter()) {
1362          *dst = src.clone();
1363        }
1364      }
1365    }
1366  };
1367}
1368
1369impl_set_all_fxn_v!(Set2DRAV,set_2d_vector_all_mat,usize);
1370impl_set_all_fxn_s!(Set2DRAS,set_2d_vector_all,usize);
1371impl_set_all_fxn_s!(Set2DRASB,set_2d_vector_all_b,bool);
1372impl_set_all_fxn_v!(Set2DRAVB,set_2d_vector_all_mat_b,bool);
1373
1374fn impl_set_range_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> Result<Box<dyn MechFunction>, MechError> {
1375  impl_set_match_arms!(Set2DRA, range_all, (sink, ixes.as_slice(), source))
1376}
1377
1378pub struct MatrixSetRangeAll {}
1379impl NativeFunctionCompiler for MatrixSetRangeAll {
1380  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1381    if arguments.len() <= 1 {
1382      return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
1383    }
1384    let sink: Value = arguments[0].clone();
1385    let source: Value = arguments[1].clone();
1386    let ixes = arguments.clone().split_off(2);
1387    match impl_set_range_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
1388      Ok(fxn) => Ok(fxn),
1389      Err(_) => {
1390        match (sink,ixes,source) {
1391          (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { impl_set_range_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
1392          (sink,ixes,Value::MutableReference(source)) => { impl_set_range_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
1393          (Value::MutableReference(sink),ixes,source) => { impl_set_range_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
1394          x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
1395        }
1396      }
1397    }
1398  }
1399}