mech_interpreter/stdlib/access/
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
11
12// Access ---------------------------------------------------------------------
13
14#[macro_export]
15macro_rules! impl_access_fxn_new {
16  ($op:tt, $fxn_name:ident, $arg:expr, $value_kind:ident, $value_string:tt) => {{
17    let mut res: MResult<_> = Err(MechError2::new(
18      GenericError { msg: "No matching type found".to_string() },
19      None
20    ));
21    
22    #[cfg(feature = "row_vector2")]
23    {
24      res = res.or_else(|_| $op!($fxn_name, RowVector2, &$arg, $value_kind, $value_string));
25    }
26
27    #[cfg(feature = "row_vector3")]
28    {
29      res = res.or_else(|_| $op!($fxn_name, RowVector3, &$arg, $value_kind, $value_string));
30    }
31
32    #[cfg(feature = "row_vector4")]
33    {
34      res = res.or_else(|_| $op!($fxn_name, RowVector4, &$arg, $value_kind, $value_string));
35    }
36
37    #[cfg(feature = "vector2")]
38    {
39      res = res.or_else(|_| $op!($fxn_name, Vector2, &$arg, $value_kind, $value_string));
40    }
41
42    #[cfg(feature = "vector3")]
43    {
44      res = res.or_else(|_| $op!($fxn_name, Vector3, &$arg, $value_kind, $value_string));
45    }
46
47    #[cfg(feature = "vector4")]
48    {
49      res = res.or_else(|_| $op!($fxn_name, Vector4, &$arg, $value_kind, $value_string));
50    }
51
52    #[cfg(feature = "matrix1")]
53    {
54      res = res.or_else(|_| $op!($fxn_name, Matrix1, &$arg, $value_kind, $value_string));
55    }
56
57    #[cfg(feature = "matrix2")]
58    {
59      res = res.or_else(|_| $op!($fxn_name, Matrix2, &$arg, $value_kind, $value_string));
60    }
61
62    #[cfg(feature = "matrix3")]
63    {
64      res = res.or_else(|_| $op!($fxn_name, Matrix3, &$arg, $value_kind, $value_string));
65    }
66
67    #[cfg(feature = "matrix4")]
68    {
69      res = res.or_else(|_| $op!($fxn_name, Matrix4, &$arg, $value_kind, $value_string));
70    }
71
72    #[cfg(feature = "matrix2x3")]
73    {
74      res = res.or_else(|_| $op!($fxn_name, Matrix2x3, &$arg, $value_kind, $value_string));
75    }
76
77    #[cfg(feature = "matrix3x2")]
78    {
79      res = res.or_else(|_| $op!($fxn_name, Matrix3x2, &$arg, $value_kind, $value_string));
80    }
81
82    #[cfg(feature = "matrixd")]
83    {
84      res = res.or_else(|_| $op!($fxn_name, DMatrix, &$arg, $value_kind, $value_string));
85    }
86
87    #[cfg(feature = "row_vectord")]
88    {
89      res = res.or_else(|_| $op!($fxn_name, RowDVector, &$arg, $value_kind, $value_string));
90    }
91
92    #[cfg(feature = "vectord")]
93    {
94      res = res.or_else(|_| $op!($fxn_name, DVector, &$arg, $value_kind, $value_string));
95    }
96
97    let (ref source, ref ixes) = &$arg;
98    res.map_err(|_| MechError2::new(
99      UnhandledFunctionArgumentIxesMono {
100        arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()),
101        fxn_name: stringify!($fxn_name).to_string(),
102      },
103      None,
104    ).with_compiler_loc())
105  }}
106}
107
108macro_rules! access_1d {
109  ($source:expr, $ix:expr, $out:expr) => {
110    unsafe { *$out = (*$source).index(*$ix - 1).clone() }
111  };}
112
113macro_rules! access_2d {
114  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
115    unsafe { 
116      *$out = (*$source).index((*$ix1 - 1, *$ix2 - 1)).clone() 
117    }
118  };}
119macro_rules! access_1d_slice {
120  ($source:expr, $ix:expr, $out:expr) => {
121    unsafe { 
122      for i in 0..(*$ix).len() {
123        ((&mut *$out))[i] = (*$source).index((&(*$ix))[i] - 1).clone();
124      }
125    }};}    
126
127macro_rules! access_1d_slice_bool {
128  ($source:expr, $ix:expr, $out:expr) => {
129    unsafe { 
130      let mut j = 0;
131      let out_len = (*$out).len();
132      for i in 0..(*$ix).len() {
133        if (*$ix)[i] == true {
134          j += 1;
135        }
136      }
137      if j != out_len {
138        (*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
139      }
140      j = 0;
141      for i in 0..(*$source).len() {
142        if (*$ix)[i] == true {
143          (&mut (*$out))[j] = (*$source).index(i).clone();
144          j += 1;
145        }
146      }
147    }};}
148
149macro_rules! access_1d_slice_bool_v {
150  ($source:expr, $ix:expr, $out:expr) => {
151    unsafe { 
152      let mut j = 0;
153      let out_len = (*$out).len();
154      for i in 0..(*$ix).len() {
155        if (&(*$ix))[i] == true {
156          j += 1;
157        }
158      }
159      if j != out_len {
160        (*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
161      }
162      j = 0;
163      for i in 0..(*$source).len() {
164        if (&(*$ix))[i] == true {
165          (&mut (*$out))[j] = (*$source).index(i).clone();
166          j += 1;
167        }
168      }
169    }};}    
170
171macro_rules! access_2d_row_slice_bool {
172  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
173    unsafe { 
174      let scalar_ix = &(*$ix1);
175      let vec_ix = &(*$ix2);
176      let mut j = 0;
177      let out_len = (*$out).len();
178      for i in 0..vec_ix.len() {
179        if vec_ix[i] == true {
180          j += 1;
181        }
182      }
183      if j != out_len {
184        (*$out).resize_horizontally_mut(j, (&(*$out))[0].clone());
185      }
186      j = 0;
187      for i in 0..vec_ix.len() {
188        if vec_ix[i] == true {
189          (&mut (*$out))[j] = (*$source).index((scalar_ix - 1, i)).clone();
190          j += 1;
191        }
192      }
193    }};}
194
195macro_rules! access_2d_col_slice_bool {
196  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
197    unsafe { 
198      let vec_ix = &(*$ix1);
199      let scalar_ix = &(*$ix2);
200      let mut j = 0;
201      let out_len = (*$out).len();
202      for i in 0..vec_ix.len() {
203        if vec_ix[i] == true {
204          j += 1;
205        }
206      }
207      if j != out_len {
208        (*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
209      }
210      j = 0;
211      for i in 0..vec_ix.len() {
212        if vec_ix[i] == true {
213          (&mut (*$out))[j] = (*$source).index((i, scalar_ix - 1)).clone();
214          j += 1;
215        }
216      }
217    }};}    
218
219macro_rules! access_2d_slice {
220  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
221    unsafe { 
222      let nrows = (*$ix1).len();
223      let ncols = (*$ix2).len();
224      let mut out_ix = 0;
225      for j in 0..ncols {
226        for i in 0..nrows {
227          (&mut (*$out))[out_ix] = (*$source).index(((&(*$ix1))[i] - 1, (&(*$ix2))[j] - 1)).clone();
228          out_ix += 1;
229        }
230      }
231    }};}
232
233macro_rules! access_2d_slice_bool {
234  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
235    unsafe { 
236      let ix1 = &(*$ix1);
237      let ix2 = &(*$ix2);
238      let mut j = 0;
239      let out_len = (*$out).len();
240      for i in 0..ix1.len() {
241        if ix1[i] == true {
242          j += 1;
243        }
244      }
245      if j != (*$out).nrows() {
246        (*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
247      }
248      j = 0;
249      for k in 0..ix2.len() {
250        for i in 0..ix1.len() {
251          if ix1[i] == true {
252            (&mut (*$out))[j] = (*$source).index((i, ix2[k] - 1)).clone();
253            j += 1;
254          }
255        }
256      }
257    }};}  
258    
259macro_rules! access_2d_slice_bool2 {
260  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
261    unsafe { 
262      let ix1 = &(*$ix1);
263      let ix2 = &(*$ix2);
264      let mut j = 0;
265      let out_len = (*$out).len();
266      for i in 0..ix2.len() {
267        if ix2[i] == true {
268          j += 1;
269        }
270      }
271      if j != (*$out).ncols() {
272        (*$out).resize_horizontally_mut(j, (& (*$out))[0].clone());
273      }
274      j = 0;
275      for k in 0..ix2.len() {
276        for i in 0..ix1.len() {
277          if ix2[k] == true {
278            (&mut (*$out))[j] = (*$source).index((ix1[i] - 1, k)).clone();
279            j += 1;
280          }
281        }
282      }
283    }};}    
284
285macro_rules! access_2d_slice_bool_bool {
286  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
287    unsafe { 
288      let ix1 = &(*$ix1);
289      let ix2 = &(*$ix2);
290      let mut k = 0;
291      let mut j = 0;
292      let out_len = (*$out).len();
293      for i in 0..ix1.len() {
294        if ix1[i] == true {
295          j += 1;
296        }
297      }
298      for i in 0..ix2.len() {
299        if ix2[i] == true {
300          k += 1;
301        }
302      }
303      if j != (*$out).nrows() || k != (*$out).ncols() {
304        (*$out).resize_mut(j, k, (&(*$out))[0].clone());
305      }
306      let mut out_ix = 0;
307      for k in 0..ix2.len() {
308        for j in 0..ix1.len() {
309          if ix1[j] == true && ix2[k] == true {
310            (&mut (*$out))[out_ix] = (*$source).index((j, k)).clone();
311            out_ix += 1;
312          }
313        }
314      }
315    }};}
316
317macro_rules! access_2d_slice_all {
318  ($source:expr, $ix:expr, $out:expr) => {
319    unsafe { 
320      let n_cols = (*$source).ncols();
321      let n_rows = (*$ix).nrows();
322      let mut out_ix = 0;
323      for c in 0..n_cols {
324        for r in 0..n_rows {
325          (&mut (*$out))[out_ix] = (*$source).index(((&(*$ix))[r] - 1, c)).clone();
326          out_ix += 1;
327        }
328      }
329    }};}
330
331macro_rules! access_2d_slice_all_bool {
332  ($source:expr, $ix:expr, $out:expr) => {
333    unsafe { 
334      let vec_ix = &(*$ix);
335      let mut j = 0;
336      let out_len = (*$out).len();
337      for i in 0..vec_ix.len() {
338        if vec_ix[i] == true {
339          j += 1;
340        }
341      }
342      if j != out_len {
343        (*$out).resize_vertically_mut(j, (&mut (*$out))[0].clone());
344      }
345      j = 0;
346      for i in 0..vec_ix.len() {
347        for k in 0..(*$source).ncols() {
348          if vec_ix[i] == true {
349            (&mut (*$out))[j] = (*$source).index((i, k)).clone();
350            j += 1;
351          }
352        }
353      }
354    }};}
355
356macro_rules! access_2d_row_slice {
357  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
358    unsafe { 
359      let ix1 = &(*$ix1);
360      let ix2 = &(*$ix2);
361      let out_cols = ix2.nrows();
362      let mut out_ix = 0;
363      for c in 0..out_cols {
364        (&mut (*$out))[out_ix] = (*$source).index((ix1 - 1, ix2[c] - 1)).clone();
365        out_ix += 1;
366      }
367    }};}    
368
369macro_rules! access_2d_col_slice {
370  ($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
371    unsafe { 
372      let ix1 = &(*$ix1);
373      let ix2 = &(*$ix2);
374      let out_rows = ix1.nrows();
375      let mut out_ix = 0;
376      for c in 0..out_rows {
377        (&mut (*$out))[out_ix] = (*$source).index((ix1[c] - 1, ix2 - 1)).clone();
378        out_ix += 1;
379      }
380    }};}    
381
382macro_rules! access_col {
383  ($source:expr, $ix:expr, $out:expr) => {
384    unsafe { 
385      for i in 0..(*$source).nrows() {
386        (&mut (*$out))[i] = (*$source).index((i, *$ix - 1)).clone();
387      }
388    }};}
389
390macro_rules! access_row {
391  ($source:expr, $ix:expr, $out:expr) => {
392    unsafe { 
393      for i in 0..(*$source).ncols() {
394        (&mut (*$out))[i] = (*$source).index((*$ix - 1, i)).clone();
395      }
396    }};}
397
398macro_rules! access_1d_all {
399  ($source:expr, $ix:expr, $out:expr) => {
400    unsafe { 
401      for i in 0..(*$source).len() {
402        (&mut (*$out))[i] = (*$source).index(i).clone();
403      }
404    }};}
405
406
407/*#[macro_export]
408macro_rules! impl_access_all_fxn_v {
409  ($struct_name:ident, $op:ident, $ix:ty) => {
410    #[derive(Debug)]
411    pub struct $struct_name<T, MatA, MatB, IxVec> {
412      pub source: Ref<MatB>,
413      pub ixes: Ref<IxVec>,
414      pub sink: Ref<MatA>,
415      pub _marker: PhantomData<T>,
416    }
417    impl<T, R1: 'static, C1: 'static, S1: 'static, R2: 'static, C2: 'static, S2: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
418    where
419      Ref<naMatrix<T, R1, C1, S1>>: ToValue,
420      Ref<naMatrix<T, R2, C2, S2>>: ToValue,
421      T: Debug + Clone + Sync + Send + 'static +
422        PartialEq + PartialOrd +
423        CompileConst + ConstElem + AsValueKind,
424      IxVec: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix]>,
425      R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
426      R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
427      naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
428      naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
429    {
430      fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
431        match args {
432          FunctionArgs::Binary(out, arg1, arg2) => {
433            let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
434            let ixes: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
435            let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
436            Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
437          },
438          _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{} requires 3 arguments, got {:?}", stringify!($struct_name), args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
439        }
440      }
441    }
442    impl<T, R1, C1, S1, R2, C2, S2, IxVec>
443      MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
444    where
445      Ref<naMatrix<T, R1, C1, S1>>: ToValue,
446      T: Debug + Clone + Sync + Send + 'static +
447         PartialEq + PartialOrd,
448      IxVec: AsRef<[$ix]> + Debug,
449      R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
450      R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
451    {
452      fn solve(&self) {
453        unsafe {
454          let sink_ptr = &mut *self.sink.as_mut_ptr();
455          let source_ptr = &*self.source.as_ptr();
456          let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
457          $op!(source_ptr,ix_ptr,sink_ptr);
458        }
459      }
460      fn out(&self) -> Value {self.sink.to_value()}
461      fn to_string(&self) -> String {format!("{:#?}", self)}
462    }
463    #[cfg(feature = "compiler")]
464    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> 
465    where
466      T: CompileConst + ConstElem + AsValueKind,
467      IxVec: CompileConst + ConstElem + AsNaKind,
468      naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
469      naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
470    {
471      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
472        let name = format!("{}<{}{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind(), naMatrix::<T, R2, C2, S2>::as_na_kind(), IxVec::as_na_kind());
473        compile_binop!(name, self.sink, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::OpAssign));
474      }
475    }  
476  };}*/
477
478macro_rules! impl_access_fxn {
479  ($struct_name:ident, $arg_type:ty, $ix_type:ty, $out_type:ty, $op:ident) => {
480    #[derive(Debug)]
481    struct $struct_name<T> {
482      source: Ref<$arg_type>,
483      ixes: Ref<$ix_type>,
484      out: Ref<$out_type>,
485    }
486    impl<T> MechFunctionFactory for $struct_name<T> 
487    where
488      T: Debug + Clone + Sync + Send + PartialEq + 'static +
489         CompileConst + ConstElem + AsValueKind,
490      Ref<$out_type>: ToValue
491    {
492      fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
493        match args {
494          FunctionArgs::Binary(out, arg1, arg2) => {
495            let n: Ref<$arg_type> = unsafe{ arg1.as_unchecked().clone() };
496            let k: Ref<$ix_type> = unsafe{ arg2.as_unchecked().clone() };
497            let out: Ref<$out_type> = unsafe{ out.as_unchecked().clone() };
498            Ok(Box::new($struct_name{source: n,ixes: k,out}))
499          }
500          _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 2, found: args.len()}, None).with_compiler_loc()),
501        }
502      }
503    }
504    impl<T> MechFunctionImpl for $struct_name<T>
505    where
506      T: Debug + Clone + Sync + Send + PartialEq + 'static,
507      Ref<$out_type>: ToValue
508    {
509      fn solve(&self) {
510        let source_ptr = self.source.as_ptr();
511        let ixes_ptr = self.ixes.as_ptr();
512        let out_ptr = self.out.as_mut_ptr();
513        $op!(source_ptr,ixes_ptr,out_ptr);
514      }
515      fn out(&self) -> Value { self.out.to_value() }
516      fn to_string(&self) -> String { format!("{:#?}", self) }
517    }
518    #[cfg(feature = "compiler")]
519    impl<T> MechFunctionCompiler for $struct_name<T> 
520    where
521      T: CompileConst + ConstElem + AsValueKind,
522    {
523      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
524        let name = format!("{}<{}>", stringify!($struct_name), T::as_value_kind());
525        compile_binop!(name, self.out, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::Access));
526      }
527    }};}
528
529macro_rules! impl_access_fxn2 {
530  ($struct_name:ident, $arg_type:ty, $ix1_type:ty, $ix2_type:ty, $out_type:ty, $op:ident) => {
531    #[derive(Debug)]
532    struct $struct_name<T> {
533      source: Ref<$arg_type>,
534      ix1: Ref<$ix1_type>,
535      ix2: Ref<$ix2_type>,
536      out: Ref<$out_type>,
537    }
538    impl<T> MechFunctionFactory for $struct_name<T> 
539    where
540      T: Debug + Clone + Sync + Send + PartialEq + 'static +
541         CompileConst + ConstElem + AsValueKind,
542      Ref<$out_type>: ToValue
543    {
544      fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
545        match args {
546          FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
547            let source: Ref<$arg_type> = unsafe{ arg1.as_unchecked().clone() };
548            let ix1: Ref<$ix1_type> = unsafe{ arg2.as_unchecked().clone() };
549            let ix2: Ref<$ix2_type> = unsafe{ arg3.as_unchecked().clone() };
550            let out: Ref<$out_type> = unsafe{ out.as_unchecked().clone() };
551            Ok(Box::new($struct_name{source ,ix1, ix2, out}))
552          }
553          _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 3, found: args.len()}, None).with_compiler_loc()),
554        }
555      }
556    }
557    impl<T> MechFunctionImpl for $struct_name<T>
558    where
559      T: Debug + Clone + Sync + Send + PartialEq + 'static,
560      Ref<$out_type>: ToValue
561    {
562      fn solve(&self) {
563        let source_ptr = self.source.as_ptr();
564        let ix1_ptr = self.ix1.as_ptr();
565        let ix2_ptr = self.ix2.as_ptr();
566        let out_ptr = self.out.as_mut_ptr();
567        $op!(source_ptr,ix1_ptr,ix2_ptr,out_ptr);
568      }
569      fn out(&self) -> Value { self.out.to_value() }
570      fn to_string(&self) -> String { format!("{:#?}", self) }
571    }
572    #[cfg(feature = "compiler")]
573    impl<T> MechFunctionCompiler for $struct_name<T> 
574    where
575      T: CompileConst + ConstElem + AsValueKind,
576    {
577      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
578        let name = format!("{}<{}>", stringify!($struct_name), T::as_value_kind());
579        compile_ternop!(name, self.out, self.source, self.ix1, self.ix2, ctx, FeatureFlag::Builtin(FeatureKind::Access) );
580      }
581    }};}    
582
583macro_rules! impl_access_fxn_shape {
584  ($name:ident, $ix_type:ty, $out_type:ty, $fxn:ident) => {
585    paste!{
586      #[cfg(feature = "matrix1")]
587      impl_access_fxn!([<$name M1>],   Matrix1<T>,    $ix_type, $out_type, $fxn);
588      #[cfg(feature = "matrix2")]
589      impl_access_fxn!([<$name M2>],   Matrix2<T>,    $ix_type, $out_type, $fxn);
590      #[cfg(feature = "matrix3")]
591      impl_access_fxn!([<$name M3>],   Matrix3<T>,    $ix_type, $out_type, $fxn);
592      #[cfg(feature = "matrix4")]
593      impl_access_fxn!([<$name M4>],   Matrix4<T>,    $ix_type, $out_type, $fxn);
594      #[cfg(feature = "matrix2x3")]
595      impl_access_fxn!([<$name M2x3>], Matrix2x3<T>,  $ix_type, $out_type, $fxn);
596      #[cfg(feature = "matrix3x2")]
597      impl_access_fxn!([<$name M3x2>], Matrix3x2<T>,  $ix_type, $out_type, $fxn);
598      #[cfg(feature = "matrixd")]
599      impl_access_fxn!([<$name MD>],   DMatrix<T>,    $ix_type, $out_type, $fxn);
600      #[cfg(feature = "vector2")]
601      impl_access_fxn!([<$name V2>],   Vector2<T>,    $ix_type, $out_type, $fxn);
602      #[cfg(feature = "vector3")]
603      impl_access_fxn!([<$name V3>],   Vector3<T>,    $ix_type, $out_type, $fxn);
604      #[cfg(feature = "vector4")]
605      impl_access_fxn!([<$name V4>],   Vector4<T>,    $ix_type, $out_type, $fxn);
606      #[cfg(feature = "vectord")]
607      impl_access_fxn!([<$name VD>],   DVector<T>,    $ix_type, $out_type, $fxn);
608      #[cfg(feature = "row_vector2")]
609      impl_access_fxn!([<$name R2>],   RowVector2<T>, $ix_type, $out_type, $fxn);
610      #[cfg(feature = "row_vector3")]
611      impl_access_fxn!([<$name R3>],   RowVector3<T>, $ix_type, $out_type, $fxn);
612      #[cfg(feature = "row_vector4")]
613      impl_access_fxn!([<$name R4>],   RowVector4<T>, $ix_type, $out_type, $fxn);
614      #[cfg(feature = "row_vectord")]
615      impl_access_fxn!([<$name RD>],   RowDVector<T>, $ix_type, $out_type, $fxn);
616    }
617  };}
618
619macro_rules! impl_access_fxn_shape2 {
620  ($name:ident, $ix1_type:ty, $ix2_type:ty, $out_type:ty, $fxn:ident) => {
621    paste!{
622      #[cfg(feature = "matrix1")]
623      impl_access_fxn2!([<$name M1>],   Matrix1<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
624      #[cfg(feature = "matrix2")]
625      impl_access_fxn2!([<$name M2>],   Matrix2<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
626      #[cfg(feature = "matrix3")]
627      impl_access_fxn2!([<$name M3>],   Matrix3<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
628      #[cfg(feature = "matrix4")]
629      impl_access_fxn2!([<$name M4>],   Matrix4<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
630      #[cfg(feature = "matrix2x3")]
631      impl_access_fxn2!([<$name M2x3>], Matrix2x3<T>,  $ix1_type, $ix2_type, $out_type, $fxn);
632      #[cfg(feature = "matrix3x2")]
633      impl_access_fxn2!([<$name M3x2>], Matrix3x2<T>,  $ix1_type, $ix2_type, $out_type, $fxn);
634      #[cfg(feature = "matrixd")]
635      impl_access_fxn2!([<$name MD>],   DMatrix<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
636      #[cfg(feature = "vector2")]
637      impl_access_fxn2!([<$name V2>],   Vector2<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
638      #[cfg(feature = "vector3")]
639      impl_access_fxn2!([<$name V3>],   Vector3<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
640      #[cfg(feature = "vector4")]
641      impl_access_fxn2!([<$name V4>],   Vector4<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
642      #[cfg(feature = "vectord")]
643      impl_access_fxn2!([<$name VD>],   DVector<T>,    $ix1_type, $ix2_type, $out_type, $fxn);
644      #[cfg(feature = "row_vector2")]
645      impl_access_fxn2!([<$name R2>],   RowVector2<T>, $ix1_type, $ix2_type, $out_type, $fxn);
646      #[cfg(feature = "row_vector3")]
647      impl_access_fxn2!([<$name R3>],   RowVector3<T>, $ix1_type, $ix2_type, $out_type, $fxn);
648      #[cfg(feature = "row_vector4")]
649      impl_access_fxn2!([<$name R4>],   RowVector4<T>, $ix1_type, $ix2_type, $out_type, $fxn);
650      #[cfg(feature = "row_vectord")]
651      impl_access_fxn2!([<$name RD>],   RowDVector<T>, $ix1_type, $ix2_type, $out_type, $fxn);
652    }
653  };}  
654
655// x[1]
656impl_access_fxn_shape!(Access1DS, usize, T, access_1d);
657
658// x[1,2]
659impl_access_fxn_shape2!(Access2DSS, usize, usize, T, access_2d);
660
661// x[1..3]
662impl_access_fxn_shape!(Access1DVD, DVector<usize>, DVector<T>, access_1d_slice);
663impl_access_fxn_shape!(Access1DVDb, DVector<bool>, DVector<T>, access_1d_slice_bool_v);
664
665// x[:]
666impl_access_fxn_shape!(Access1DA, Value, DVector<T>, access_1d_all);
667
668// x[:,1]
669impl_access_fxn_shape!(Access2DAS, usize, DVector<T>, access_col);
670
671// x[1,:]
672#[cfg(feature = "matrix1")]
673impl_access_fxn!(Access2DSAM1,   Matrix1<T>,    usize, Matrix1<T>, access_row);
674#[cfg(all(feature = "matrix2", feature = "row_vector2"))]
675impl_access_fxn!(Access2DSAM2,   Matrix2<T>,    usize, RowVector2<T>, access_row);
676#[cfg(all(feature = "matrix3", feature = "row_vector3"))]
677impl_access_fxn!(Access2DSAM3,   Matrix3<T>,    usize, RowVector3<T>, access_row);
678#[cfg(all(feature = "matrix4", feature = "row_vector4"))]
679impl_access_fxn!(Access2DSAM4,   Matrix4<T>,    usize, RowVector4<T>, access_row);
680#[cfg(all(feature = "matrix2x3", feature = "row_vector3"))]
681impl_access_fxn!(Access2DSAM2x3, Matrix2x3<T>,  usize, RowVector3<T>, access_row);
682#[cfg(all(feature = "matrix3x2", feature = "row_vector2"))]
683impl_access_fxn!(Access2DSAM3x2, Matrix3x2<T>,  usize, RowVector2<T>, access_row);
684#[cfg(all(feature = "matrixd", feature = "row_vectord"))]
685impl_access_fxn!(Access2DSAMD,   DMatrix<T>,    usize, RowDVector<T>, access_row);
686
687// x[1..3,:]
688impl_access_fxn_shape!(Access2DVDA, DVector<usize>,    DMatrix<T>, access_2d_slice_all);
689impl_access_fxn_shape!(Access2DVDbA, DVector<bool>,    DMatrix<T>, access_2d_slice_all_bool);
690
691// x[2,1..3]
692impl_access_fxn_shape2!(Access2DSVD,  usize, DVector<usize>,    RowDVector<T>, access_2d_row_slice);
693impl_access_fxn_shape2!(Access2DSVDb, usize, DVector<bool>,     RowDVector<T>, access_2d_row_slice_bool);
694
695// x[1..3,2]
696impl_access_fxn_shape2!(Access2DVDS,  DVector<usize>, usize,    DVector<T>, access_2d_col_slice);
697impl_access_fxn_shape2!(Access2DVDbS, DVector<bool>, usize,     DVector<T>, access_2d_col_slice_bool);
698
699macro_rules! impl_access_match_arms {
700  ($fxn_name:ident,$macro_name:ident, $arg:expr) => {
701    paste!{
702      [<impl_access_ $macro_name _match_arms>]!(
703        $fxn_name,
704        $arg,
705        Bool => MatrixBool, bool, bool::default(), "bool";
706        I8   => MatrixI8,   i8,   i8::default(),  "i8";
707        I16  => MatrixI16,  i16,  i16::default(), "i16";
708        I32  => MatrixI32,  i32,  i32::default(), "i32";
709        I64  => MatrixI64,  i64,  i64::default(), "i64";
710        I128 => MatrixI128, i128, i128::default(), "i128";
711        U8   => MatrixU8,   u8,   u8::default(), "u8";
712        U16  => MatrixU16,  u16,  u16::default(), "u16";
713        U32  => MatrixU32,  u32,  u32::default(), "u32";
714        U64  => MatrixU64,  u64,  u64::default(), "u64";
715        U128 => MatrixU128, u128, u128::default(), "u128";
716        F32  => MatrixF32,  f32,  f32::default(), "f32";
717        F64  => MatrixF64,  f64,  f64::default(), "f64";
718        String => MatrixString, String, String::default(), "string";
719        C64 => MatrixC64, C64, C64::default(), "complex";
720        R64 => MatrixR64, R64, R64::default(), "rational";
721      )
722    }
723  }
724}
725
726// x[1] -----------------------------------------------------------------------
727
728macro_rules! impl_access_scalar_match_arms {
729  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
730    paste!{
731      match $arg {
732        $(
733          $(
734            #[cfg(all(feature = $value_string, feature = "row_vector4"))]              
735            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::Index(ix)]) => {
736              register_fxn_descriptor_inner!([<$fxn_name R4>], $target_type, $value_string);
737              Ok(Box::new([<$fxn_name R4>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
738            },
739            #[cfg(all(feature = $value_string, feature = "row_vector3"))]              
740            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::Index(ix)]) => {
741              register_fxn_descriptor_inner!([<$fxn_name R3>], $target_type, $value_string);
742              Ok(Box::new([<$fxn_name R3>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
743            },
744            #[cfg(all(feature = $value_string, feature = "row_vector2"))]              
745            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::Index(ix)]) => {
746              register_fxn_descriptor_inner!([<$fxn_name R2>], $target_type, $value_string);
747              Ok(Box::new([<$fxn_name R2>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
748            },
749            #[cfg(all(feature = $value_string, feature = "vector4"))]              
750            (Value::$matrix_kind(Matrix::Vector4(input)),    [Value::Index(ix)]) => {
751              register_fxn_descriptor_inner!([<$fxn_name V4>], $target_type, $value_string);
752              Ok(Box::new([<$fxn_name V4>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
753            },
754            #[cfg(all(feature = $value_string, feature = "vector3"))]              
755            (Value::$matrix_kind(Matrix::Vector3(input)),    [Value::Index(ix)]) => {
756              register_fxn_descriptor_inner!([<$fxn_name V3>], $target_type, $value_string);
757              Ok(Box::new([<$fxn_name V3>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
758            },
759            #[cfg(all(feature = $value_string, feature = "vector2"))]              
760            (Value::$matrix_kind(Matrix::Vector2(input)),    [Value::Index(ix)]) => {
761              register_fxn_descriptor_inner!([<$fxn_name V2>], $target_type, $value_string);
762              Ok(Box::new([<$fxn_name V2>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
763            },
764            #[cfg(all(feature = $value_string, feature = "matrix4"))]              
765            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::Index(ix)]) => {
766              register_fxn_descriptor_inner!([<$fxn_name M4>], $target_type, $value_string);
767              Ok(Box::new([<$fxn_name M4>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
768            },
769            #[cfg(all(feature = $value_string, feature = "matrix3"))]              
770            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::Index(ix)]) => {
771              register_fxn_descriptor_inner!([<$fxn_name M3>], $target_type, $value_string);
772              Ok(Box::new([<$fxn_name M3>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
773            },
774            #[cfg(all(feature = $value_string, feature = "matrix2"))]              
775            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::Index(ix)]) => {
776              register_fxn_descriptor_inner!([<$fxn_name M2>], $target_type, $value_string);
777              Ok(Box::new([<$fxn_name M2>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
778            },
779            #[cfg(all(feature = $value_string, feature = "matrix1"))]              
780            (Value::$matrix_kind(Matrix::Matrix1(input)),    [Value::Index(ix)]) => {
781              register_fxn_descriptor_inner!([<$fxn_name M1>], $target_type, $value_string);
782              Ok(Box::new([<$fxn_name M1>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
783            },
784            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]              
785            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::Index(ix)]) => {
786              register_fxn_descriptor_inner!([<$fxn_name M2x3>], $target_type, $value_string);
787              Ok(Box::new([<$fxn_name M2x3>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
788            },
789            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]              
790            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::Index(ix)]) => {
791              register_fxn_descriptor_inner!([<$fxn_name M3x2>], $target_type, $value_string);
792              Ok(Box::new([<$fxn_name M3x2>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
793            },
794            #[cfg(all(feature = $value_string, feature = "row_vectord"))]              
795            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::Index(ix)]) => {
796              register_fxn_descriptor_inner!([<$fxn_name RD>], $target_type, $value_string);
797              Ok(Box::new([<$fxn_name RD>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
798            },
799            #[cfg(all(feature = $value_string, feature = "vectord"))]              
800            (Value::$matrix_kind(Matrix::DVector(input)),    [Value::Index(ix)]) => {
801              register_fxn_descriptor_inner!([<$fxn_name VD>], $target_type, $value_string);
802              Ok(Box::new([<$fxn_name VD>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
803            },
804            #[cfg(all(feature = $value_string, feature = "matrixd"))]              
805            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::Index(ix)]) => {
806              register_fxn_descriptor_inner!([<$fxn_name MD>], $target_type, $value_string);
807              Ok(Box::new([<$fxn_name MD>]  {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
808            },
809          )+
810        )+
811        (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
812      }
813    }
814  }
815}
816
817fn impl_access_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
818  impl_access_match_arms!(Access1DS, scalar, (lhs_value, ixes.as_slice()))
819}
820
821pub struct MatrixAccessScalar {}
822impl NativeFunctionCompiler for MatrixAccessScalar {
823  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
824    if arguments.len() <= 1 {
825      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
826    }
827    let ixes = arguments.clone().split_off(1);
828    let mat = arguments[0].clone();
829    match impl_access_scalar_fxn(mat.clone(), ixes.clone()) {
830      Ok(fxn) => Ok(fxn),
831      Err(_) => {
832        match (mat,ixes) {
833          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
834          (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalar".to_string() }, None).with_compiler_loc()),
835        }
836      }
837    }
838  }
839}
840
841// x[1,2] ---------------------------------------------------------------------
842
843macro_rules! impl_access_scalar_scalar_match_arms {
844  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
845    paste!{
846      match $arg {
847        $(
848          $(
849            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
850            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
851              register_fxn_descriptor_inner!([<$fxn_name R4>], $target_type, $value_string);
852              Ok(Box::new([<$fxn_name R4>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
853            },
854            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
855            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
856              register_fxn_descriptor_inner!([<$fxn_name R3>], $target_type, $value_string);
857              Ok(Box::new([<$fxn_name R3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
858            },
859            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
860            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
861              register_fxn_descriptor_inner!([<$fxn_name R2>], $target_type, $value_string);
862              Ok(Box::new([<$fxn_name R2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
863            },
864            #[cfg(all(feature = $value_string, feature = "vector4"))]
865            (Value::$matrix_kind(Matrix::Vector4(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
866              register_fxn_descriptor_inner!([<$fxn_name V4>], $target_type, $value_string);
867              Ok(Box::new([<$fxn_name V4>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
868            },
869            #[cfg(all(feature = $value_string, feature = "vector3"))]
870            (Value::$matrix_kind(Matrix::Vector3(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
871              register_fxn_descriptor_inner!([<$fxn_name V3>], $target_type, $value_string);
872              Ok(Box::new([<$fxn_name V3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
873            },
874            #[cfg(all(feature = $value_string, feature = "vector2"))]
875            (Value::$matrix_kind(Matrix::Vector2(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
876              register_fxn_descriptor_inner!([<$fxn_name V2>], $target_type, $value_string);
877              Ok(Box::new([<$fxn_name V2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
878            },
879            #[cfg(all(feature = $value_string, feature = "matrix4"))]
880            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
881              register_fxn_descriptor_inner!([<$fxn_name M4>], $target_type, $value_string);
882              Ok(Box::new([<$fxn_name M4>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
883            },
884            #[cfg(all(feature = $value_string, feature = "matrix3"))]
885            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
886              register_fxn_descriptor_inner!([<$fxn_name M3>], $target_type, $value_string);
887              Ok(Box::new([<$fxn_name M3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
888            },
889            #[cfg(all(feature = $value_string, feature = "matrix2"))]
890            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
891              register_fxn_descriptor_inner!([<$fxn_name M2>], $target_type, $value_string);
892              Ok(Box::new([<$fxn_name M2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
893            },
894            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
895            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::Index(ix1),Value::Index(ix2)]) => {
896              register_fxn_descriptor_inner!([<$fxn_name M2x3>], $target_type, $value_string);
897              Ok(Box::new([<$fxn_name M2x3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
898            },
899            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
900            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::Index(ix1),Value::Index(ix2)]) => {
901              register_fxn_descriptor_inner!([<$fxn_name M3x2>], $target_type, $value_string);
902              Ok(Box::new([<$fxn_name M3x2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
903            },
904            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
905            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
906              register_fxn_descriptor_inner!([<$fxn_name RD>], $target_type, $value_string);
907              Ok(Box::new([<$fxn_name RD>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
908            },
909            #[cfg(all(feature = $value_string, feature = "vectord"))]
910            (Value::$matrix_kind(Matrix::DVector(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
911              register_fxn_descriptor_inner!([<$fxn_name VD>], $target_type, $value_string);
912              Ok(Box::new([<$fxn_name VD>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
913            },
914            #[cfg(all(feature = $value_string, feature = "matrixd"))]
915            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
916              register_fxn_descriptor_inner!([<$fxn_name MD>], $target_type, $value_string);
917              Ok(Box::new([<$fxn_name MD>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
918            },
919          )+
920        )+
921        (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
922      }
923    }
924  }
925}
926
927fn impl_access_scalar_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
928  impl_access_match_arms!(Access2DSS, scalar_scalar, (lhs_value, ixes.as_slice()))
929}
930
931pub struct MatrixAccessScalarScalar {}
932impl NativeFunctionCompiler for MatrixAccessScalarScalar {
933  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
934    if arguments.len() <= 2 {
935      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
936    }
937    let ixes = arguments.clone().split_off(1);
938    let mat = arguments[0].clone();
939    match impl_access_scalar_scalar_fxn(mat.clone(), ixes.clone()) {
940      Ok(fxn) => Ok(fxn),
941      Err(_) => {
942        match (mat,ixes) {
943          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
944          (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarScalar".to_string() }, None).with_compiler_loc()),
945        }
946      }
947    }
948  }
949}
950
951// x[1..3] --------------------------------------------------------------------
952
953macro_rules! impl_access_range_match_arms {
954  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
955    paste!{
956      match $arg {
957        $(
958          $(
959            #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "logical_indexing"))]
960            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
961              register_fxn_descriptor_inner!(Access1DVDbR4, $target_type, $value_string);
962              Ok(Box::new(Access1DVDbR4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
963            },    
964            #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "logical_indexing"))]
965            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
966              register_fxn_descriptor_inner!(Access1DVDbR3, $target_type, $value_string);
967              Ok(Box::new(Access1DVDbR3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
968            },    
969            #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "logical_indexing"))]
970            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
971              register_fxn_descriptor_inner!(Access1DVDbR2, $target_type, $value_string);
972              Ok(Box::new(Access1DVDbR2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
973            },    
974            #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "logical_indexing"))]
975            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
976              register_fxn_descriptor_inner!(Access1DVDbRD, $target_type, $value_string);
977              Ok(Box::new(Access1DVDbRD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
978            },   
979
980            // --
981
982            #[cfg(all(feature = $value_string, feature = "vector4", feature = "logical_indexing"))]
983            (Value::$matrix_kind(Matrix::Vector4(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
984              register_fxn_descriptor_inner!(Access1DVDbV4, $target_type, $value_string);
985              Ok(Box::new(Access1DVDbV4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
986            },    
987            #[cfg(all(feature = $value_string, feature = "vector3", feature = "logical_indexing"))]
988            (Value::$matrix_kind(Matrix::Vector3(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
989              register_fxn_descriptor_inner!(Access1DVDbV3, $target_type, $value_string);
990              Ok(Box::new(Access1DVDbV3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
991            },    
992            #[cfg(all(feature = $value_string, feature = "vector2", feature = "logical_indexing"))]
993            (Value::$matrix_kind(Matrix::Vector2(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
994              register_fxn_descriptor_inner!(Access1DVDbV2, $target_type, $value_string);
995              Ok(Box::new(Access1DVDbV2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
996            },    
997            #[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
998            (Value::$matrix_kind(Matrix::DVector(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
999              register_fxn_descriptor_inner!(Access1DVDbVD, $target_type, $value_string);
1000              Ok(Box::new(Access1DVDbVD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1001            },   
1002
1003            // -- 
1004
1005            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1006            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1007              register_fxn_descriptor_inner!(Access1DVDbM4, $target_type, $value_string);
1008              Ok(Box::new(Access1DVDbM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1009            },              
1010            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1011            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1012              register_fxn_descriptor_inner!(Access1DVDbM3, $target_type, $value_string);
1013              Ok(Box::new(Access1DVDbM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1014            },    
1015            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1016            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1017              register_fxn_descriptor_inner!(Access1DVDbM2, $target_type, $value_string);
1018              Ok(Box::new(Access1DVDbM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1019            },    
1020            #[cfg(all(feature = $value_string, feature = "matrix1", feature = "logical_indexing"))]
1021            (Value::$matrix_kind(Matrix::Matrix1(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1022              register_fxn_descriptor_inner!(Access1DVDbM1, $target_type, $value_string);
1023              Ok(Box::new(Access1DVDbM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1024            },    
1025            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1026            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1027              register_fxn_descriptor_inner!(Access1DVDbM3x2, $target_type, $value_string);
1028              Ok(Box::new(Access1DVDbM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1029            },              
1030            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
1031            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1032              register_fxn_descriptor_inner!(Access1DVDbM2x3, $target_type, $value_string);
1033              Ok(Box::new(Access1DVDbM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1034            },              
1035            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
1036            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1037              register_fxn_descriptor_inner!(Access1DVDbMD, $target_type, $value_string);
1038              Ok(Box::new(Access1DVDbMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1039            },   
1040
1041            // --
1042
1043            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
1044            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1045              register_fxn_descriptor_inner!(Access1DVDR4, $target_type, $value_string);
1046              Ok(Box::new(Access1DVDR4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1047            },                
1048            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
1049            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1050              register_fxn_descriptor_inner!(Access1DVDR3, $target_type, $value_string);
1051              Ok(Box::new(Access1DVDR3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1052            },    
1053            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
1054            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1055              register_fxn_descriptor_inner!(Access1DVDR2, $target_type, $value_string);
1056              Ok(Box::new(Access1DVDR2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1057            },    
1058            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
1059            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1060              register_fxn_descriptor_inner!(Access1DVDRD, $target_type, $value_string);
1061              Ok(Box::new(Access1DVDRD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1062            },   
1063
1064            // --
1065
1066            #[cfg(all(feature = $value_string, feature = "vector4"))]
1067            (Value::$matrix_kind(Matrix::Vector4(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1068              register_fxn_descriptor_inner!(Access1DVDV4, $target_type, $value_string);
1069              Ok(Box::new(Access1DVDV4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1070            },                
1071            #[cfg(all(feature = $value_string, feature = "vector3"))]
1072            (Value::$matrix_kind(Matrix::Vector3(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1073              register_fxn_descriptor_inner!(Access1DVDV3, $target_type, $value_string);
1074              Ok(Box::new(Access1DVDV3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1075            },    
1076            #[cfg(all(feature = $value_string, feature = "vector2"))]
1077            (Value::$matrix_kind(Matrix::Vector2(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1078              register_fxn_descriptor_inner!(Access1DVDV2, $target_type, $value_string);
1079              Ok(Box::new(Access1DVDV2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1080            },    
1081            #[cfg(all(feature = $value_string, feature = "vectord"))]
1082            (Value::$matrix_kind(Matrix::DVector(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1083              register_fxn_descriptor_inner!(Access1DVDVD, $target_type, $value_string);
1084              Ok(Box::new(Access1DVDVD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1085            },   
1086
1087            // --
1088
1089            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1090            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1091              register_fxn_descriptor_inner!(Access1DVDM4, $target_type, $value_string);
1092              Ok(Box::new(Access1DVDM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1093            },                
1094            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1095            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1096              register_fxn_descriptor_inner!(Access1DVDM3, $target_type, $value_string);
1097              Ok(Box::new(Access1DVDM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1098            },    
1099            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1100            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1101              register_fxn_descriptor_inner!(Access1DVDM2, $target_type, $value_string);
1102              Ok(Box::new(Access1DVDM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1103            },    
1104            #[cfg(all(feature = $value_string, feature = "matrix1"))]
1105            (Value::$matrix_kind(Matrix::Matrix1(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1106              register_fxn_descriptor_inner!(Access1DVDM1, $target_type, $value_string);
1107              Ok(Box::new(Access1DVDM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1108            },    
1109            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1110            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
1111              register_fxn_descriptor_inner!(Access1DVDM3x2, $target_type, $value_string);
1112              Ok(Box::new(Access1DVDM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1113            },    
1114            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1115            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
1116              register_fxn_descriptor_inner!(Access1DVDM2x3, $target_type, $value_string);
1117              Ok(Box::new(Access1DVDM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1118            },    
1119            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1120            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1121              register_fxn_descriptor_inner!(Access1DVDMD, $target_type, $value_string);
1122              Ok(Box::new(Access1DVDMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1123            },   
1124          )+
1125        )+
1126        (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
1127      }
1128    }
1129  }
1130}
1131
1132fn impl_access_range_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1133  impl_access_match_arms!(Access1DR, range, (lhs_value, ixes.as_slice()))
1134}
1135
1136pub struct MatrixAccessRange {}
1137impl NativeFunctionCompiler for MatrixAccessRange {
1138  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1139    if arguments.len() <= 1 {
1140      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1141    }
1142    let ixes = arguments.clone().split_off(1);
1143    let mat = arguments[0].clone();
1144    match impl_access_range_fxn(mat.clone(), ixes.clone()) {
1145      Ok(fxn) => Ok(fxn),
1146      Err(_) => {
1147        match (mat,ixes) {
1148          (Value::MutableReference(lhs),rhs_value) => { impl_access_range_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1149          (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRange".to_string() }, None).with_compiler_loc()),
1150        }
1151      }
1152    }
1153  }
1154}
1155
1156// x[1..3,1..3] ---------------------------------------------------------------
1157
1158macro_rules! access_2d_range_range_vbb {
1159  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1160    unsafe { 
1161      let mut sink_rix = 0;
1162      let mut sink_cix = 0;
1163      for r in 0..($ix1).len() {
1164        if ($ix1)[r] == true {
1165          for c in 0..($ix2).len() {
1166            if ($ix2)[c] == true {
1167              ($sink)[(sink_rix, sink_cix)] = ($source)[(r, c)].clone();
1168              sink_cix += 1;
1169            }
1170          }
1171          sink_cix = 0;
1172          sink_rix += 1;
1173        }
1174      }
1175    }
1176  };}
1177
1178macro_rules! access_2d_range_range_vuu {
1179  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1180    unsafe { 
1181      let mut sink_rix = 0;
1182      let mut sink_cix = 0;
1183      for r in 0..($ix1).len() {
1184        let row = ($ix1)[r] - 1;
1185        for c in 0..($ix2).len() {
1186          let col = ($ix2)[c] - 1;
1187          ($sink)[(sink_rix, sink_cix)] = ($source)[(row, col)].clone();
1188          sink_cix += 1;
1189        }
1190        sink_cix = 0;
1191        sink_rix += 1;
1192      }
1193    }
1194  };}
1195
1196macro_rules! access_2d_range_range_vub {
1197  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1198    unsafe { 
1199      let mut sink_rix = 0;
1200      let mut sink_cix = 0;
1201      for r in 0..($ix1).len() {
1202        let row = ($ix1)[r] - 1;
1203        for c in 0..($ix2).len() {
1204          if ($ix2)[c] == true {
1205            ($sink)[(sink_rix, sink_cix)] = ($source)[(row, c)].clone();
1206            sink_cix += 1;
1207          }
1208        }
1209        sink_cix = 0;
1210        sink_rix += 1;
1211      }
1212    }
1213  };}
1214
1215macro_rules! access_2d_range_range_vbu {
1216  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1217    unsafe { 
1218      let mut sink_rix = 0;
1219      let mut sink_cix = 0;
1220      for r in 0..($ix1).len() {
1221        if ($ix1)[r] == true {
1222          for c in 0..($ix2).len() {
1223            let col = ($ix2)[c] - 1;
1224            ($sink)[(sink_rix, sink_cix)] = ($source)[(r, col)].clone();
1225            sink_cix += 1;
1226          }
1227          sink_cix = 0;
1228          sink_rix += 1;
1229        }
1230      }
1231    }
1232  };}
1233
1234macro_rules! impl_access_range_range_arms {
1235  ($fxn_name:ident, $shape:tt, $arg:expr, $value_kind:ident, $value_string:tt) => {
1236    paste!{
1237      match $arg {
1238        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
1239        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1240          register_assign_srr2!([<$fxn_name VUU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1241          box_mech_fxn(Ok(Box::new([<$fxn_name VUU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(ix1.borrow().len(), ix2.borrow().len(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1242        },
1243        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord", feature = "row_vectord", feature = "logical_indexing"))]
1244        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1245          let rows = ix1.borrow().iter().filter(|x| **x).count();
1246          let cols = ix2.borrow().iter().filter(|x| **x).count();
1247          match (cols, rows) {
1248            #[cfg(feature = "matrixd")]
1249            (1, 1) => {
1250              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1251              box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(1, 1, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1252            },
1253            #[cfg(feature = "vectord")]
1254            (1, _) => {
1255              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
1256              box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DVector::from_element(rows, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1257            },
1258            #[cfg(feature = "row_vectord")]
1259            (_, 1) => {
1260              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
1261              box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1262            },
1263            #[cfg(feature = "matrixd")]
1264            _ => {
1265              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1266              box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(rows, cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1267            },
1268          }
1269        },
1270        #[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
1271        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1272          let cols = ix2.borrow().iter().filter(|x| **x).count();
1273          let rows = ix1.borrow().len();
1274          match (cols, rows) {
1275            #[cfg(feature = "matrixd")]
1276            (1, 1) => {
1277              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1278              box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(1, 1, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1279            },
1280            #[cfg(feature = "vectord")]
1281            (1, _) => {
1282              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
1283              box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DVector::from_element(rows, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1284            },
1285            #[cfg(feature = "row_vectord")]
1286            (_, 1) => {
1287              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
1288              box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1289            },
1290            #[cfg(feature = "matrixd")]
1291            _ => {
1292              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1293              box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(rows, cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1294            },
1295          }
1296        },
1297         #[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
1298        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1299          let cols = ix2.borrow().len();
1300          let rows = ix1.borrow().iter().filter(|x| **x).count();
1301          match (cols, rows) {
1302            #[cfg(feature = "matrixd")]
1303            (1, 1) => {
1304              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1305              box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(1, 1, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1306            },
1307            #[cfg(feature = "vectord")]
1308            (1, _) => {
1309              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
1310              box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DVector::from_element(rows, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1311            },
1312            #[cfg(feature = "row_vectord")]
1313            (_, 1) => {
1314              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
1315              box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1316            },
1317            #[cfg(feature = "matrixd")]
1318            _ => {
1319              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1320              box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(rows, cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1321            },
1322          }
1323        }
1324        (src, ix) => Err(MechError2::new(
1325          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1326          None).with_compiler_loc()
1327        ),
1328      }
1329    }
1330  }
1331}
1332
1333impl_range_range_fxn_v!(Access2DRRVBB, access_2d_range_range_vbb, bool,  bool);
1334impl_range_range_fxn_v!(Access2DRRVBU, access_2d_range_range_vbu, bool,  usize);
1335impl_range_range_fxn_v!(Access2DRRVUU, access_2d_range_range_vuu, usize, usize);
1336impl_range_range_fxn_v!(Access2DRRVUB, access_2d_range_range_vub, usize, bool);
1337
1338fn matrix_access_range_range_fxn(source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1339  let arg = (source.clone(), ixes.as_slice());
1340               impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u8,   "u8")
1341  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u16,  "u16"))
1342  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u32,  "u32"))
1343  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u64,  "u64"))
1344  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u128, "u128"))
1345  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i8,   "i8"))
1346  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i16,  "i16"))
1347  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i32,  "i32"))
1348  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i64,  "i64"))
1349  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i128, "i128"))
1350  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, f32,  "f32"))
1351  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, f64,  "f64"))
1352  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, R64,  "rational"))
1353  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, C64,  "complex"))
1354  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, bool, "bool"))
1355  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, String, "string"))
1356  .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxesMono{
1357      arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()
1358    }, None).with_compiler_loc())
1359}
1360    
1361pub struct MatrixAccessRangeRange {}
1362impl NativeFunctionCompiler for MatrixAccessRangeRange {
1363  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1364    if arguments.len() <= 1 {
1365      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1366    }
1367    let source: Value = arguments[0].clone();
1368    let ixes = arguments.clone().split_off(1);
1369    match matrix_access_range_range_fxn(source.clone(), ixes.clone()) {
1370      Ok(fxn) => Ok(fxn),
1371      Err(_) => {
1372        match source {
1373          Value::MutableReference(source) => { matrix_access_range_range_fxn(source.borrow().clone(), ixes.clone()) },
1374          _ => Err(MechError2::new(
1375            UnhandledFunctionArgumentIxesMono{arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()}, 
1376            None).with_compiler_loc()
1377          ),
1378        }
1379      }
1380    }
1381  }
1382}
1383
1384// x[:] -----------------------------------------------------------------------
1385
1386macro_rules! impl_access_all_match_arms {
1387  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1388    paste!{
1389      match $arg {
1390        $(
1391            $(
1392            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1393            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::IndexAll]) => {
1394              register_fxn_descriptor_inner!(Access1DAM4, $target_type, $value_string);
1395              Ok(Box::new(Access1DAM4  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1396            },
1397            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1398            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::IndexAll]) => {
1399              register_fxn_descriptor_inner!(Access1DAM3, $target_type, $value_string);
1400              Ok(Box::new(Access1DAM3  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1401            },
1402            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1403            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::IndexAll]) => {
1404              register_fxn_descriptor_inner!(Access1DAM2, $target_type, $value_string);
1405              Ok(Box::new(Access1DAM2  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1406            },
1407            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1408            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::IndexAll]) => {
1409              register_fxn_descriptor_inner!(Access1DAM3x2, $target_type, $value_string);
1410              Ok(Box::new(Access1DAM3x2{source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1411            },
1412            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1413            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::IndexAll]) => {
1414              register_fxn_descriptor_inner!(Access1DAM2x3, $target_type, $value_string);
1415              Ok(Box::new(Access1DAM2x3{source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1416            },
1417            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1418            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::IndexAll]) => {
1419              register_fxn_descriptor_inner!(Access1DAMD, $target_type, $value_string);
1420              Ok(Box::new(Access1DAMD  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1421            },
1422          )+
1423        )+
1424        (src, ix) => Err(MechError2::new(
1425          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1426          None).with_compiler_loc()
1427        ),
1428      }
1429    }
1430  }
1431}
1432
1433fn impl_access_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1434  impl_access_match_arms!(Access1DA, all, (lhs_value, ixes.as_slice()))
1435}
1436
1437pub struct MatrixAccessAll {}
1438impl NativeFunctionCompiler for MatrixAccessAll {
1439  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1440    if arguments.len() <= 1 {
1441      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1442    }
1443    let ixes = arguments.clone().split_off(1);
1444    let mat = arguments[0].clone();
1445    match impl_access_all_fxn(mat.clone(), ixes.clone()) {
1446      Ok(fxn) => Ok(fxn),
1447      Err(_) => {
1448        match (mat,ixes) {
1449          (Value::MutableReference(lhs),rhs_value) => { impl_access_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1450          (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAll".to_string()}, None).with_compiler_loc()),
1451        }
1452      }
1453    }
1454  }
1455}
1456
1457// x[:,2] ---------------------------------------------------------------------
1458
1459macro_rules! impl_access_all_scalar_match_arms {
1460  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1461    paste!{
1462      match $arg {
1463        $(
1464            $(
1465            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1466            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1467              register_fxn_descriptor_inner!(Access2DASM4, $target_type, $value_string);
1468              Ok(Box::new(Access2DASM4  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1469            },
1470            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1471            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1472              register_fxn_descriptor_inner!(Access2DASM3, $target_type, $value_string);
1473              Ok(Box::new(Access2DASM3  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1474            },
1475            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1476            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1477              register_fxn_descriptor_inner!(Access2DASM2, $target_type, $value_string);
1478              Ok(Box::new(Access2DASM2  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1479            },
1480            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1481            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::IndexAll,Value::Index(ix)]) => {
1482              register_fxn_descriptor_inner!(Access2DASM2x3, $target_type, $value_string);
1483              Ok(Box::new(Access2DASM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1484            },
1485            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1486            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::IndexAll,Value::Index(ix)]) => {
1487              register_fxn_descriptor_inner!(Access2DASM3x2, $target_type, $value_string);
1488              Ok(Box::new(Access2DASM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1489            },
1490            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1491            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1492              register_fxn_descriptor_inner!(Access2DASMD, $target_type, $value_string);
1493              Ok(Box::new(Access2DASMD  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1494            },
1495          )+
1496        )+
1497        (src, ix) => Err(MechError2::new(
1498          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1499          None).with_compiler_loc()
1500        ),
1501      }
1502    }
1503  }
1504}
1505
1506fn impl_access_all_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1507  impl_access_match_arms!(Access2DAS, all_scalar, (lhs_value, ixes.as_slice()))
1508}
1509
1510pub struct MatrixAccessAllScalar {}
1511impl NativeFunctionCompiler for MatrixAccessAllScalar {
1512  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1513    if arguments.len() <= 2 {
1514      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1515    }
1516    let ixes = arguments.clone().split_off(1);
1517    let mat = arguments[0].clone();
1518    match impl_access_all_scalar_fxn(mat.clone(), ixes.clone()) {
1519      Ok(fxn) => Ok(fxn),
1520      Err(_) => {
1521        match (mat,ixes) {
1522          (Value::MutableReference(lhs),rhs_value) => { impl_access_all_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1523          (src, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllScalar".to_string()}, None).with_compiler_loc()),
1524        }
1525      }
1526    }
1527  }
1528}
1529
1530// x[2,:] ---------------------------------------------------------------------
1531
1532macro_rules! impl_access_scalar_all_match_arms {
1533  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1534    paste!{
1535      match $arg {
1536        $(
1537            $(
1538            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "row_vector4"))]
1539            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix),Value::IndexAll]) => {
1540              register_fxn_descriptor_inner!(Access2DSAM4, $target_type, $value_string);
1541              Ok(Box::new(Access2DSAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector4::from_element($default)) }))
1542            },
1543            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "row_vector3"))]
1544            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix),Value::IndexAll]) => {
1545              register_fxn_descriptor_inner!(Access2DSAM3, $target_type, $value_string);
1546              Ok(Box::new(Access2DSAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector3::from_element($default)) }))
1547            },
1548            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "row_vector2"))]
1549            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix),Value::IndexAll]) => {
1550              register_fxn_descriptor_inner!(Access2DSAM2, $target_type, $value_string);
1551              Ok(Box::new(Access2DSAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector2::from_element($default)) }))
1552            },
1553            #[cfg(all(feature = $value_string, feature = "matrix1", feature = "matrix1"))]
1554            (Value::$matrix_kind(Matrix::Matrix1(input)), [Value::Index(ix),Value::IndexAll]) => {
1555              register_fxn_descriptor_inner!(Access2DSAM1, $target_type, $value_string);
1556              Ok(Box::new(Access2DSAM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(Matrix1::from_element($default)) }))
1557            },
1558            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "row_vector2"))]
1559            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix),Value::IndexAll]) => {
1560              register_fxn_descriptor_inner!(Access2DSAM3x2, $target_type, $value_string);
1561              Ok(Box::new(Access2DSAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector2::from_element($default)) }))
1562            },
1563            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "row_vector3"))]
1564            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix),Value::IndexAll]) => {
1565              register_fxn_descriptor_inner!(Access2DSAM2x3, $target_type, $value_string);
1566              Ok(Box::new(Access2DSAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector3::from_element($default)) }))
1567            },
1568            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "row_vectord"))]
1569            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix),Value::IndexAll]) => {
1570              register_fxn_descriptor_inner!(Access2DSAMD, $target_type, $value_string);
1571              Ok(Box::new(Access2DSAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowDVector::from_element(input.borrow().ncols(),$default)) }))
1572            },
1573          )+
1574        )+
1575        (src, ix) => Err(MechError2::new(
1576          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1577          None).with_compiler_loc()
1578        ),
1579      }
1580    }
1581  }
1582}
1583
1584fn impl_access_scalar_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1585 impl_access_match_arms!(Access2DSA, scalar_all, (lhs_value, ixes.as_slice()))
1586}
1587
1588pub struct MatrixAccessScalarAll {}
1589impl NativeFunctionCompiler for MatrixAccessScalarAll {
1590  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1591    if arguments.len() <= 2 {
1592      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1593    }
1594    let ixes = arguments.clone().split_off(1);
1595    let mat = arguments[0].clone();
1596    match impl_access_scalar_all_fxn(mat.clone(), ixes.clone()) {
1597      Ok(fxn) => Ok(fxn),
1598      Err(_) => {
1599        match (mat,ixes) {
1600          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1601          (mat, ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{arg: (mat.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarAll".to_string()}, None).with_compiler_loc()),
1602        }
1603      }
1604    }
1605  }
1606}
1607
1608// x[:,1..3] ---------------------------------------------------------------------
1609
1610macro_rules! assign_2d_all_range_v {
1611  ($source:expr, $ix:expr, $sink:expr) => {
1612    {
1613      let mut sink_col_ix = 0;
1614      for i in 0..(*$ix).len() {
1615        let col_ix = $ix[i] - 1;
1616        let mut sink_col = ($sink).column_mut(sink_col_ix);
1617        let src_col = ($source).column(col_ix);
1618        for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
1619          *dst = src.clone();
1620        }
1621        sink_col_ix += 1;
1622      }
1623    }
1624  };}
1625
1626macro_rules! assign_2d_all_range_vb {
1627  ($source:expr, $ix:expr, $sink:expr) => {
1628    {
1629      let mut sink_col_ix = 0;
1630      for i in 0..(*$source).ncols() {
1631        if $ix[i] == true {
1632          let mut sink_col = ($sink).column_mut(sink_col_ix);
1633          let src_col = ($source).column(i);
1634          for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
1635            *dst = src.clone();
1636          }
1637          sink_col_ix += 1;
1638        }
1639      }
1640    }
1641  };}
1642
1643macro_rules! impl_access_all_range_arms {
1644  ($fxn_name:ident, $shape:tt, $arg:expr, $value_kind:ident, $value_string:tt) => {
1645    paste!{
1646      match $arg {
1647        // All Vector
1648        #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "vectord"))]
1649        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixIndex(Matrix::DVector(ix))]) if source.borrow().nrows() == 1 => {
1650          register_assign!([<$fxn_name V>], $value_kind, $value_string, RowDVector, $shape, DVector);
1651          box_mech_fxn(Ok(Box::new([<$fxn_name V>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(RowDVector::from_element(ix.borrow().len(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1652        },
1653        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
1654        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixIndex(Matrix::DVector(ix))]) => {
1655          register_assign!([<$fxn_name V>], $value_kind, $value_string, DMatrix, $shape, DVector);
1656          box_mech_fxn(Ok(Box::new([<$fxn_name V>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(DMatrix::from_element(source.borrow().nrows(), ix.borrow().len(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1657        },
1658        // All Bool Vector
1659        #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "vectord"))]
1660        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) if source.borrow().nrows() == 1 => {
1661          let cols = ix.borrow().iter().filter(|&&b| b).count();
1662          register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, RowDVector, $shape, DVector);
1663          box_mech_fxn(Ok(Box::new([<$fxn_name VB>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1664        },
1665        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing", feature = "vectord"))]
1666        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) if ix.borrow().iter().filter(|&&b| b).count() == 1 && source.borrow().nrows() != 1 => {
1667          register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, DVector, $shape, DVector);
1668          box_mech_fxn(Ok(Box::new([<$fxn_name VB>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(DVector::from_element(source.borrow().nrows(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1669        },
1670        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing", feature = "vectord"))]
1671        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) => {
1672          let cols = ix.borrow().iter().filter(|&&b| b).count();
1673          register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, DMatrix, $shape, DVector);
1674          box_mech_fxn(Ok(Box::new([<$fxn_name VB>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(DMatrix::from_element(source.borrow().nrows(), cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
1675        },
1676        (sink, ix) => {
1677          Err(MechError2::new(
1678            UnhandledFunctionArgumentIxesMono{arg: (sink.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1679            None).with_compiler_loc()
1680          )
1681        }
1682      }
1683    }
1684  }
1685}
1686
1687impl_all_fxn_v!(Access2DARV,  assign_2d_all_range_v,  usize);
1688impl_all_fxn_v!(Access2DARVB, assign_2d_all_range_vb, bool);
1689
1690fn matrix_access_all_range_fxn(source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1691  let arg = (source.clone(), ixes.as_slice());
1692               impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u8,   "u8")
1693  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u16,  "u16"))
1694  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u32,  "u32"))
1695  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u64,  "u64"))
1696  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u128, "u128"))
1697  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i8,   "i8"))
1698  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i16,  "i16"))
1699  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i32,  "i32"))
1700  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i64,  "i64"))
1701  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i128, "i128"))
1702  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, f32,  "f32"))
1703  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, f64,  "f64"))
1704  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, R64,  "rational"))
1705  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, C64,  "complex"))
1706  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, bool, "bool"))
1707  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, String, "string"))
1708  .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxesMono{
1709      arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllRange".to_string()
1710    }, None).with_compiler_loc())
1711}
1712    
1713pub struct MatrixAccessAllRange {}
1714impl NativeFunctionCompiler for MatrixAccessAllRange {
1715  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1716    if arguments.len() <= 1 {
1717      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1718    }
1719    let source: Value = arguments[0].clone();
1720    let ixes = arguments.clone().split_off(1);
1721    match matrix_access_all_range_fxn(source.clone(), ixes.clone()) {
1722      Ok(fxn) => Ok(fxn),
1723      Err(_) => {
1724        match source {
1725          Value::MutableReference(source) => { matrix_access_all_range_fxn(source.borrow().clone(), ixes.clone()) },
1726          x => Err(MechError2::new(
1727            UnhandledFunctionArgumentIxesMono{arg: (x.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllRange".to_string()}, 
1728            None).with_compiler_loc()
1729          ),
1730        }
1731      }
1732    }
1733  }
1734}
1735
1736// x[1..3,:] ---------------------------------------------------------------------
1737
1738macro_rules! impl_access_range_all_match_arms {
1739  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1740    paste!{
1741      match $arg {
1742        $(
1743          $(
1744            // Vector All
1745            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1746            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1747              register_fxn_descriptor_inner!(Access2DVDAM4, $target_type, $value_string);
1748              Ok(Box::new(Access2DVDAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1749            },
1750            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1751            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1752              register_fxn_descriptor_inner!(Access2DVDAM3, $target_type, $value_string);
1753              Ok(Box::new(Access2DVDAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1754            },
1755            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1756            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1757              register_fxn_descriptor_inner!(Access2DVDAM2, $target_type, $value_string);
1758              Ok(Box::new(Access2DVDAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1759            },
1760            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1761            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1762              register_fxn_descriptor_inner!(Access2DVDAM3x2, $target_type, $value_string);
1763              Ok(Box::new(Access2DVDAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1764            },
1765            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1766            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1767              register_fxn_descriptor_inner!(Access2DVDAM2x3, $target_type, $value_string);
1768              Ok(Box::new(Access2DVDAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1769            },
1770            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1771            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1772              register_fxn_descriptor_inner!(Access2DVDAMD, $target_type, $value_string);
1773              Ok(Box::new(Access2DVDAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1774            },
1775            // Bool Vector All
1776            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1777            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1778              register_fxn_descriptor_inner!(Access2DVDbAM4, $target_type, $value_string);
1779              Ok(Box::new(Access2DVDbAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1780            },
1781            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1782            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1783              register_fxn_descriptor_inner!(Access2DVDbAM3, $target_type, $value_string);
1784              Ok(Box::new(Access2DVDbAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1785            },
1786            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1787            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1788              register_fxn_descriptor_inner!(Access2DVDbAM2, $target_type, $value_string);
1789              Ok(Box::new(Access2DVDbAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1790            },
1791            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1792            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1793              register_fxn_descriptor_inner!(Access2DVDbAM3x2, $target_type, $value_string);
1794              Ok(Box::new(Access2DVDbAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1795            },
1796            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
1797            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1798              register_fxn_descriptor_inner!(Access2DVDbAM2x3, $target_type, $value_string);
1799              Ok(Box::new(Access2DVDbAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1800            },
1801            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
1802            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1803              register_fxn_descriptor_inner!(Access2DVDbAMD, $target_type, $value_string);
1804              Ok(Box::new(Access2DVDbAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1805            },
1806          )+
1807        )+
1808        (src, ixes) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeAll".to_string()}, None).with_compiler_loc()),
1809      }
1810    }
1811  }
1812}
1813
1814fn impl_access_range_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1815  impl_access_match_arms!(Access2DRA, range_all, (lhs_value, ixes.as_slice()))
1816}
1817
1818  pub struct MatrixAccessRangeAll {}
1819impl NativeFunctionCompiler for MatrixAccessRangeAll {
1820  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1821    if arguments.len() <= 2 {
1822      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1823    }
1824    let ixes = arguments.clone().split_off(1);
1825    let mat = arguments[0].clone();
1826    match impl_access_range_all_fxn(mat.clone(), ixes.clone()) {
1827      Ok(fxn) => Ok(fxn),
1828      Err(_) => {
1829        match (mat.clone(),ixes.clone()) {
1830          (Value::MutableReference(lhs),rhs_value) => { impl_access_range_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1831          (src, ixes) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeAll".to_string()}, None).with_compiler_loc()),
1832        }
1833      }
1834    }
1835  }
1836}
1837
1838// x[1..3,2] ---------------------------------------------------------------------
1839
1840macro_rules! impl_access_range_scalar_match_arms {
1841  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1842    paste!{
1843      match $arg {
1844        $(
1845            $(
1846            // Vector Scalar
1847            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1848            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1849              register_fxn_descriptor_inner!(Access2DVDSM4, $target_type, $value_string);
1850              Ok(Box::new(Access2DVDSM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1851            },
1852            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1853            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1854              register_fxn_descriptor_inner!(Access2DVDSM3, $target_type, $value_string);
1855              Ok(Box::new(Access2DVDSM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1856            },
1857            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1858            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1859              register_fxn_descriptor_inner!(Access2DVDSM2, $target_type, $value_string);
1860              Ok(Box::new(Access2DVDSM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1861            },
1862            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1863            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1864              register_fxn_descriptor_inner!(Access2DVDSM2x3, $target_type, $value_string);
1865              Ok(Box::new(Access2DVDSM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1866            },
1867            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1868            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1869              register_fxn_descriptor_inner!(Access2DVDSM3x2, $target_type, $value_string);
1870              Ok(Box::new(Access2DVDSM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1871            },
1872            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1873            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1874              register_fxn_descriptor_inner!(Access2DVDSMD, $target_type, $value_string);
1875              Ok(Box::new(Access2DVDSMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1876            },
1877            // Bool Vector Scalar
1878            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1879            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1880              register_fxn_descriptor_inner!(Access2DVDbSM4, $target_type, $value_string);
1881              Ok(Box::new(Access2DVDbSM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1882            },
1883            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1884            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1885              register_fxn_descriptor_inner!(Access2DVDbSM3, $target_type, $value_string);
1886              Ok(Box::new(Access2DVDbSM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1887            },
1888            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1889            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1890              register_fxn_descriptor_inner!(Access2DVDbSM2, $target_type, $value_string);
1891              Ok(Box::new(Access2DVDbSM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1892            },
1893            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
1894            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1895              register_fxn_descriptor_inner!(Access2DVDbSM2x3, $target_type, $value_string);
1896              Ok(Box::new(Access2DVDbSM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1897            },
1898            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1899            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1900              register_fxn_descriptor_inner!(Access2DVDbSM3x2, $target_type, $value_string);
1901              Ok(Box::new(Access2DVDbSM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1902            },
1903            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
1904            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1905              register_fxn_descriptor_inner!(Access2DVDbSMD, $target_type, $value_string);
1906              Ok(Box::new(Access2DVDbSMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1907            },)+
1908        )+
1909        (src, ixes) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()}, None).with_compiler_loc()),
1910      }
1911    }
1912  }
1913}
1914
1915fn impl_access_range_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1916  impl_access_match_arms!(Access2DRS, range_scalar, (lhs_value, ixes.as_slice()))
1917}
1918
1919pub struct MatrixAccessRangeScalar {}
1920impl NativeFunctionCompiler for MatrixAccessRangeScalar {
1921  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1922    if arguments.len() <= 2 {
1923      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1924    }
1925    let ixes = arguments.clone().split_off(1);
1926    let mat = arguments[0].clone();
1927    match impl_access_range_scalar_fxn(mat.clone(), ixes.clone()) {
1928      Ok(fxn) => Ok(fxn),
1929      Err(_) => {
1930        match (mat,ixes) {
1931          (Value::MutableReference(lhs),rhs_value) => { impl_access_range_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1932          (src,ixs) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ixs.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeScalar".to_string() }, None).with_compiler_loc()),
1933        }
1934      }
1935    }
1936  }
1937}
1938
1939// x[2,1..3] ---------------------------------------------------------------------
1940
1941macro_rules! impl_access_scalar_range_match_arms {
1942  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1943    paste!{
1944      match $arg {
1945        $(
1946          $(
1947            // Scalar Vector 
1948            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1949            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1950              register_fxn_descriptor_inner!(Access2DSVDM4, $target_type, $value_string);
1951              Ok(Box::new(Access2DSVDM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1952            },
1953            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1954            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1955              register_fxn_descriptor_inner!(Access2DSVDM3, $target_type, $value_string);
1956              Ok(Box::new(Access2DSVDM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1957            },
1958            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1959            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1960              register_fxn_descriptor_inner!(Access2DSVDM2, $target_type, $value_string);
1961              Ok(Box::new(Access2DSVDM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1962            },
1963            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1964            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1965              register_fxn_descriptor_inner!(Access2DSVDM3x2, $target_type, $value_string);
1966              Ok(Box::new(Access2DSVDM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1967            },
1968            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1969            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1970              register_fxn_descriptor_inner!(Access2DSVDM2x3, $target_type, $value_string);
1971              Ok(Box::new(Access2DSVDM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1972            },
1973            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1974            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1975              register_fxn_descriptor_inner!(Access2DSVDMD, $target_type, $value_string);
1976              Ok(Box::new(Access2DSVDMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1977            },
1978            // Bool Scalar Vector
1979            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1980            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1981              register_fxn_descriptor_inner!(Access2DSVDbM4, $target_type, $value_string);
1982              Ok(Box::new(Access2DSVDbM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1983            },
1984            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1985            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1986              register_fxn_descriptor_inner!(Access2DSVDbM3, $target_type, $value_string);
1987              Ok(Box::new(Access2DSVDbM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1988            },
1989            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1990            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1991              register_fxn_descriptor_inner!(Access2DSVDbM2, $target_type, $value_string);
1992              Ok(Box::new(Access2DSVDbM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1993            },
1994            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1995            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1996              register_fxn_descriptor_inner!(Access2DSVDbM3x2, $target_type, $value_string);
1997              Ok(Box::new(Access2DSVDbM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
1998            },
1999            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
2000            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2001              register_fxn_descriptor_inner!(Access2DSVDbM2x3, $target_type, $value_string);
2002              Ok(Box::new(Access2DSVDbM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2003            },
2004            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
2005            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2006              register_fxn_descriptor_inner!(Access2DSVDbMD, $target_type, $value_string);
2007              Ok(Box::new(Access2DSVDbMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2008            },)+
2009        )+
2010        (src,ix) => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{ arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
2011      }
2012    }
2013  }
2014}
2015
2016fn impl_access_scalar_range_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
2017  impl_access_match_arms!(Access2DSR, scalar_range, (lhs_value, ixes.as_slice()))
2018}
2019
2020pub struct MatrixAccessScalarRange {}
2021
2022impl NativeFunctionCompiler for MatrixAccessScalarRange {
2023  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
2024    if arguments.len() <= 2 {
2025      return Err(MechError2::new(IncorrectNumberOfArguments{expected: 1, found: arguments.len()}, None).with_compiler_loc());
2026    }
2027    let ixes = arguments.clone().split_off(1);
2028    let mat = arguments[0].clone();
2029    match impl_access_scalar_range_fxn(mat.clone(), ixes.clone()) {
2030      Ok(fxn) => Ok(fxn),
2031      Err(_) => {
2032        match (mat.clone(),ixes.clone()) {
2033          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_range_fxn(lhs.borrow().clone(), rhs_value.clone()) }
2034          x => Err(MechError2::new(UnhandledFunctionArgumentIxesMono{ arg: (mat.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarRange".to_string() }, None).with_compiler_loc()),
2035        }
2036      }
2037    }
2038  }
2039}