Skip to main content

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(MechError::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(|_| MechError::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(MechError::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(MechError::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(MechError::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
821#[derive(Debug)]
822struct MatrixAccessScalarValueF {
823  source: Matrix<Value>,
824  ix: Ref<usize>,
825  out: Ref<Value>,
826  element_kind: ValueKind,
827}
828
829impl MechFunctionImpl for MatrixAccessScalarValueF {
830  fn solve(&self) {
831    let ix = *self.ix.borrow();
832    let value = self.source.index1d(ix);
833    *self.out.borrow_mut() = match &self.element_kind {
834      ValueKind::Option(_) => Value::Typed(Box::new(value), self.element_kind.clone()),
835      _ => value,
836    };
837  }
838  fn out(&self) -> Value { self.out.borrow().clone() }
839  fn to_string(&self) -> String { format!("{:#?}", self) }
840}
841
842#[cfg(feature = "compiler")]
843impl MechFunctionCompiler for MatrixAccessScalarValueF {
844  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
845    let mut registers = [0,0,0];
846    registers[0] = compile_register_brrw!(self.out, ctx);
847    registers[1] = compile_register!(self.source, ctx);
848    registers[2] = compile_register_brrw!(self.ix, ctx);
849    ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Access));
850    ctx.emit_binop(
851      hash_str("MatrixAccessScalarValueF"),
852      registers[0],
853      registers[1],
854      registers[2],
855    );
856    Ok(registers[0])
857  }
858}
859
860pub struct MatrixAccessScalar {}
861impl NativeFunctionCompiler for MatrixAccessScalar {
862  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
863    if arguments.len() <= 1 {
864      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
865    }
866    let ixes = arguments.clone().split_off(1);
867    let mat = arguments[0].clone();
868    if let (Value::MatrixValue(source), [Value::Index(ix)]) = (mat.clone(), ixes.as_slice()) {
869      let element_kind = match mat.kind() {
870        ValueKind::Matrix(elem, _) => (*elem).clone(),
871        _ => ValueKind::Any,
872      };
873      let init = match &element_kind {
874        ValueKind::Option(_) => Value::Typed(Box::new(Value::Empty), element_kind.clone()),
875        _ => Value::Empty,
876      };
877      return Ok(Box::new(MatrixAccessScalarValueF {
878        source,
879        ix: ix.clone(),
880        out: Ref::new(init),
881        element_kind,
882      }));
883    }
884    match impl_access_scalar_fxn(mat.clone(), ixes.clone()) {
885      Ok(fxn) => Ok(fxn),
886      Err(_) => {
887        match (mat,ixes) {
888          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
889          (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalar".to_string() }, None).with_compiler_loc()),
890        }
891      }
892    }
893  }
894}
895
896// x[1,2] ---------------------------------------------------------------------
897
898macro_rules! impl_access_scalar_scalar_match_arms {
899  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
900    paste!{
901      match $arg {
902        $(
903          $(
904            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
905            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
906              register_fxn_descriptor_inner!([<$fxn_name R4>], $target_type, $value_string);
907              Ok(Box::new([<$fxn_name R4>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
908            },
909            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
910            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
911              register_fxn_descriptor_inner!([<$fxn_name R3>], $target_type, $value_string);
912              Ok(Box::new([<$fxn_name R3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
913            },
914            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
915            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
916              register_fxn_descriptor_inner!([<$fxn_name R2>], $target_type, $value_string);
917              Ok(Box::new([<$fxn_name R2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
918            },
919            #[cfg(all(feature = $value_string, feature = "vector4"))]
920            (Value::$matrix_kind(Matrix::Vector4(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
921              register_fxn_descriptor_inner!([<$fxn_name V4>], $target_type, $value_string);
922              Ok(Box::new([<$fxn_name V4>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
923            },
924            #[cfg(all(feature = $value_string, feature = "vector3"))]
925            (Value::$matrix_kind(Matrix::Vector3(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
926              register_fxn_descriptor_inner!([<$fxn_name V3>], $target_type, $value_string);
927              Ok(Box::new([<$fxn_name V3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
928            },
929            #[cfg(all(feature = $value_string, feature = "vector2"))]
930            (Value::$matrix_kind(Matrix::Vector2(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
931              register_fxn_descriptor_inner!([<$fxn_name V2>], $target_type, $value_string);
932              Ok(Box::new([<$fxn_name V2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
933            },
934            #[cfg(all(feature = $value_string, feature = "matrix4"))]
935            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
936              register_fxn_descriptor_inner!([<$fxn_name M4>], $target_type, $value_string);
937              Ok(Box::new([<$fxn_name M4>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
938            },
939            #[cfg(all(feature = $value_string, feature = "matrix3"))]
940            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
941              register_fxn_descriptor_inner!([<$fxn_name M3>], $target_type, $value_string);
942              Ok(Box::new([<$fxn_name M3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
943            },
944            #[cfg(all(feature = $value_string, feature = "matrix2"))]
945            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
946              register_fxn_descriptor_inner!([<$fxn_name M2>], $target_type, $value_string);
947              Ok(Box::new([<$fxn_name M2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
948            },
949            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
950            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::Index(ix1),Value::Index(ix2)]) => {
951              register_fxn_descriptor_inner!([<$fxn_name M2x3>], $target_type, $value_string);
952              Ok(Box::new([<$fxn_name M2x3>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
953            },
954            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
955            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::Index(ix1),Value::Index(ix2)]) => {
956              register_fxn_descriptor_inner!([<$fxn_name M3x2>], $target_type, $value_string);
957              Ok(Box::new([<$fxn_name M3x2>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
958            },
959            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
960            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
961              register_fxn_descriptor_inner!([<$fxn_name RD>], $target_type, $value_string);
962              Ok(Box::new([<$fxn_name RD>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
963            },
964            #[cfg(all(feature = $value_string, feature = "vectord"))]
965            (Value::$matrix_kind(Matrix::DVector(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
966              register_fxn_descriptor_inner!([<$fxn_name VD>], $target_type, $value_string);
967              Ok(Box::new([<$fxn_name VD>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
968            },
969            #[cfg(all(feature = $value_string, feature = "matrixd"))]
970            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::Index(ix1),Value::Index(ix2)]) => {
971              register_fxn_descriptor_inner!([<$fxn_name MD>], $target_type, $value_string);
972              Ok(Box::new([<$fxn_name MD>]  {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
973            },
974          )+
975        )+
976        (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
977      }
978    }
979  }
980}
981
982fn impl_access_scalar_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
983  impl_access_match_arms!(Access2DSS, scalar_scalar, (lhs_value, ixes.as_slice()))
984}
985
986pub struct MatrixAccessScalarScalar {}
987impl NativeFunctionCompiler for MatrixAccessScalarScalar {
988  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
989    if arguments.len() <= 2 {
990      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
991    }
992    let ixes = arguments.clone().split_off(1);
993    let mat = arguments[0].clone();
994    match impl_access_scalar_scalar_fxn(mat.clone(), ixes.clone()) {
995      Ok(fxn) => Ok(fxn),
996      Err(_) => {
997        match (mat,ixes) {
998          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
999          (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarScalar".to_string() }, None).with_compiler_loc()),
1000        }
1001      }
1002    }
1003  }
1004}
1005
1006// x[1..3] --------------------------------------------------------------------
1007
1008macro_rules! impl_access_range_match_arms {
1009  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1010    paste!{
1011      match $arg {
1012        $(
1013          $(
1014            #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "logical_indexing"))]
1015            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
1016              register_fxn_descriptor_inner!(Access1DVDbR4, $target_type, $value_string);
1017              Ok(Box::new(Access1DVDbR4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1018            },    
1019            #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "logical_indexing"))]
1020            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
1021              register_fxn_descriptor_inner!(Access1DVDbR3, $target_type, $value_string);
1022              Ok(Box::new(Access1DVDbR3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1023            },    
1024            #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "logical_indexing"))]
1025            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
1026              register_fxn_descriptor_inner!(Access1DVDbR2, $target_type, $value_string);
1027              Ok(Box::new(Access1DVDbR2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1028            },    
1029            #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "logical_indexing"))]
1030            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::MatrixBool(Matrix::DVector(ix))])     => {
1031              register_fxn_descriptor_inner!(Access1DVDbRD, $target_type, $value_string);
1032              Ok(Box::new(Access1DVDbRD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1033            },   
1034
1035            // --
1036
1037            #[cfg(all(feature = $value_string, feature = "vector4", feature = "logical_indexing"))]
1038            (Value::$matrix_kind(Matrix::Vector4(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1039              register_fxn_descriptor_inner!(Access1DVDbV4, $target_type, $value_string);
1040              Ok(Box::new(Access1DVDbV4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1041            },    
1042            #[cfg(all(feature = $value_string, feature = "vector3", feature = "logical_indexing"))]
1043            (Value::$matrix_kind(Matrix::Vector3(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1044              register_fxn_descriptor_inner!(Access1DVDbV3, $target_type, $value_string);
1045              Ok(Box::new(Access1DVDbV3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1046            },    
1047            #[cfg(all(feature = $value_string, feature = "vector2", feature = "logical_indexing"))]
1048            (Value::$matrix_kind(Matrix::Vector2(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1049              register_fxn_descriptor_inner!(Access1DVDbV2, $target_type, $value_string);
1050              Ok(Box::new(Access1DVDbV2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1051            },    
1052            #[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
1053            (Value::$matrix_kind(Matrix::DVector(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1054              register_fxn_descriptor_inner!(Access1DVDbVD, $target_type, $value_string);
1055              Ok(Box::new(Access1DVDbVD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1056            },   
1057
1058            // -- 
1059
1060            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1061            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1062              register_fxn_descriptor_inner!(Access1DVDbM4, $target_type, $value_string);
1063              Ok(Box::new(Access1DVDbM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1064            },              
1065            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1066            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1067              register_fxn_descriptor_inner!(Access1DVDbM3, $target_type, $value_string);
1068              Ok(Box::new(Access1DVDbM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1069            },    
1070            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1071            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1072              register_fxn_descriptor_inner!(Access1DVDbM2, $target_type, $value_string);
1073              Ok(Box::new(Access1DVDbM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1074            },    
1075            #[cfg(all(feature = $value_string, feature = "matrix1", feature = "logical_indexing"))]
1076            (Value::$matrix_kind(Matrix::Matrix1(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1077              register_fxn_descriptor_inner!(Access1DVDbM1, $target_type, $value_string);
1078              Ok(Box::new(Access1DVDbM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1079            },    
1080            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1081            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1082              register_fxn_descriptor_inner!(Access1DVDbM3x2, $target_type, $value_string);
1083              Ok(Box::new(Access1DVDbM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1084            },              
1085            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
1086            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1087              register_fxn_descriptor_inner!(Access1DVDbM2x3, $target_type, $value_string);
1088              Ok(Box::new(Access1DVDbM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1089            },              
1090            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
1091            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix))])  => {
1092              register_fxn_descriptor_inner!(Access1DVDbMD, $target_type, $value_string);
1093              Ok(Box::new(Access1DVDbMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1094            },   
1095
1096            // --
1097
1098            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
1099            (Value::$matrix_kind(Matrix::RowVector4(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1100              register_fxn_descriptor_inner!(Access1DVDR4, $target_type, $value_string);
1101              Ok(Box::new(Access1DVDR4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1102            },                
1103            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
1104            (Value::$matrix_kind(Matrix::RowVector3(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1105              register_fxn_descriptor_inner!(Access1DVDR3, $target_type, $value_string);
1106              Ok(Box::new(Access1DVDR3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1107            },    
1108            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
1109            (Value::$matrix_kind(Matrix::RowVector2(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1110              register_fxn_descriptor_inner!(Access1DVDR2, $target_type, $value_string);
1111              Ok(Box::new(Access1DVDR2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1112            },    
1113            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
1114            (Value::$matrix_kind(Matrix::RowDVector(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1115              register_fxn_descriptor_inner!(Access1DVDRD, $target_type, $value_string);
1116              Ok(Box::new(Access1DVDRD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1117            },   
1118
1119            // --
1120
1121            #[cfg(all(feature = $value_string, feature = "vector4"))]
1122            (Value::$matrix_kind(Matrix::Vector4(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1123              register_fxn_descriptor_inner!(Access1DVDV4, $target_type, $value_string);
1124              Ok(Box::new(Access1DVDV4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1125            },                
1126            #[cfg(all(feature = $value_string, feature = "vector3"))]
1127            (Value::$matrix_kind(Matrix::Vector3(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1128              register_fxn_descriptor_inner!(Access1DVDV3, $target_type, $value_string);
1129              Ok(Box::new(Access1DVDV3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1130            },    
1131            #[cfg(all(feature = $value_string, feature = "vector2"))]
1132            (Value::$matrix_kind(Matrix::Vector2(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1133              register_fxn_descriptor_inner!(Access1DVDV2, $target_type, $value_string);
1134              Ok(Box::new(Access1DVDV2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1135            },    
1136            #[cfg(all(feature = $value_string, feature = "vectord"))]
1137            (Value::$matrix_kind(Matrix::DVector(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1138              register_fxn_descriptor_inner!(Access1DVDVD, $target_type, $value_string);
1139              Ok(Box::new(Access1DVDVD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1140            },   
1141
1142            // --
1143
1144            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1145            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1146              register_fxn_descriptor_inner!(Access1DVDM4, $target_type, $value_string);
1147              Ok(Box::new(Access1DVDM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1148            },                
1149            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1150            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1151              register_fxn_descriptor_inner!(Access1DVDM3, $target_type, $value_string);
1152              Ok(Box::new(Access1DVDM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1153            },    
1154            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1155            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1156              register_fxn_descriptor_inner!(Access1DVDM2, $target_type, $value_string);
1157              Ok(Box::new(Access1DVDM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1158            },    
1159            #[cfg(all(feature = $value_string, feature = "matrix1"))]
1160            (Value::$matrix_kind(Matrix::Matrix1(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1161              register_fxn_descriptor_inner!(Access1DVDM1, $target_type, $value_string);
1162              Ok(Box::new(Access1DVDM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1163            },    
1164            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1165            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
1166              register_fxn_descriptor_inner!(Access1DVDM3x2, $target_type, $value_string);
1167              Ok(Box::new(Access1DVDM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1168            },    
1169            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1170            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
1171              register_fxn_descriptor_inner!(Access1DVDM2x3, $target_type, $value_string);
1172              Ok(Box::new(Access1DVDM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1173            },    
1174            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1175            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix))])  => {
1176              register_fxn_descriptor_inner!(Access1DVDMD, $target_type, $value_string);
1177              Ok(Box::new(Access1DVDMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
1178            },   
1179          )+
1180        )+
1181        (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
1182      }
1183    }
1184  }
1185}
1186
1187fn impl_access_range_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1188  impl_access_match_arms!(Access1DR, range, (lhs_value, ixes.as_slice()))
1189}
1190
1191pub struct MatrixAccessRange {}
1192impl NativeFunctionCompiler for MatrixAccessRange {
1193  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1194    if arguments.len() <= 1 {
1195      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1196    }
1197    let ixes = arguments.clone().split_off(1);
1198    let mat = arguments[0].clone();
1199    match impl_access_range_fxn(mat.clone(), ixes.clone()) {
1200      Ok(fxn) => Ok(fxn),
1201      Err(_) => {
1202        match (mat,ixes) {
1203          (Value::MutableReference(lhs),rhs_value) => { impl_access_range_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1204          (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRange".to_string() }, None).with_compiler_loc()),
1205        }
1206      }
1207    }
1208  }
1209}
1210
1211// x[1..3,1..3] ---------------------------------------------------------------
1212
1213macro_rules! access_2d_range_range_vbb {
1214  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1215    unsafe { 
1216      let mut sink_rix = 0;
1217      let mut sink_cix = 0;
1218      for r in 0..($ix1).len() {
1219        if ($ix1)[r] == true {
1220          for c in 0..($ix2).len() {
1221            if ($ix2)[c] == true {
1222              ($sink)[(sink_rix, sink_cix)] = ($source)[(r, c)].clone();
1223              sink_cix += 1;
1224            }
1225          }
1226          sink_cix = 0;
1227          sink_rix += 1;
1228        }
1229      }
1230    }
1231  };}
1232
1233macro_rules! access_2d_range_range_vuu {
1234  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1235    unsafe { 
1236      let mut sink_rix = 0;
1237      let mut sink_cix = 0;
1238      for r in 0..($ix1).len() {
1239        let row = ($ix1)[r] - 1;
1240        for c in 0..($ix2).len() {
1241          let col = ($ix2)[c] - 1;
1242          ($sink)[(sink_rix, sink_cix)] = ($source)[(row, col)].clone();
1243          sink_cix += 1;
1244        }
1245        sink_cix = 0;
1246        sink_rix += 1;
1247      }
1248    }
1249  };}
1250
1251macro_rules! access_2d_range_range_vub {
1252  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1253    unsafe { 
1254      let mut sink_rix = 0;
1255      let mut sink_cix = 0;
1256      for r in 0..($ix1).len() {
1257        let row = ($ix1)[r] - 1;
1258        for c in 0..($ix2).len() {
1259          if ($ix2)[c] == true {
1260            ($sink)[(sink_rix, sink_cix)] = ($source)[(row, c)].clone();
1261            sink_cix += 1;
1262          }
1263        }
1264        sink_cix = 0;
1265        sink_rix += 1;
1266      }
1267    }
1268  };}
1269
1270macro_rules! access_2d_range_range_vbu {
1271  ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1272    unsafe { 
1273      let mut sink_rix = 0;
1274      let mut sink_cix = 0;
1275      for r in 0..($ix1).len() {
1276        if ($ix1)[r] == true {
1277          for c in 0..($ix2).len() {
1278            let col = ($ix2)[c] - 1;
1279            ($sink)[(sink_rix, sink_cix)] = ($source)[(r, col)].clone();
1280            sink_cix += 1;
1281          }
1282          sink_cix = 0;
1283          sink_rix += 1;
1284        }
1285      }
1286    }
1287  };}
1288
1289macro_rules! impl_access_range_range_arms {
1290  ($fxn_name:ident, $shape:tt, $arg:expr, $value_kind:ident, $value_string:tt) => {
1291    paste!{
1292      match $arg {
1293        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
1294        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1295          register_assign_srr2!([<$fxn_name VUU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1296          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() })))
1297        },
1298        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord", feature = "row_vectord", feature = "logical_indexing"))]
1299        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1300          let rows = ix1.borrow().iter().filter(|x| **x).count();
1301          let cols = ix2.borrow().iter().filter(|x| **x).count();
1302          match (cols, rows) {
1303            #[cfg(feature = "matrixd")]
1304            (1, 1) => {
1305              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1306              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() })))
1307            },
1308            #[cfg(feature = "vectord")]
1309            (1, _) => {
1310              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
1311              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() })))
1312            },
1313            #[cfg(feature = "row_vectord")]
1314            (_, 1) => {
1315              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
1316              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() })))
1317            },
1318            #[cfg(feature = "matrixd")]
1319            _ => {
1320              register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1321              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() })))
1322            },
1323          }
1324        },
1325        #[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
1326        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))]) => {
1327          let cols = ix2.borrow().iter().filter(|x| **x).count();
1328          let rows = ix1.borrow().len();
1329          match (cols, rows) {
1330            #[cfg(feature = "matrixd")]
1331            (1, 1) => {
1332              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1333              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() })))
1334            },
1335            #[cfg(feature = "vectord")]
1336            (1, _) => {
1337              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
1338              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() })))
1339            },
1340            #[cfg(feature = "row_vectord")]
1341            (_, 1) => {
1342              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
1343              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() })))
1344            },
1345            #[cfg(feature = "matrixd")]
1346            _ => {
1347              register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1348              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() })))
1349            },
1350          }
1351        },
1352         #[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
1353        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
1354          let cols = ix2.borrow().len();
1355          let rows = ix1.borrow().iter().filter(|x| **x).count();
1356          match (cols, rows) {
1357            #[cfg(feature = "matrixd")]
1358            (1, 1) => {
1359              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1360              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() })))
1361            },
1362            #[cfg(feature = "vectord")]
1363            (1, _) => {
1364              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
1365              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() })))
1366            },
1367            #[cfg(feature = "row_vectord")]
1368            (_, 1) => {
1369              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
1370              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() })))
1371            },
1372            #[cfg(feature = "matrixd")]
1373            _ => {
1374              register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
1375              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() })))
1376            },
1377          }
1378        }
1379        (src, ix) => Err(MechError::new(
1380          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1381          None).with_compiler_loc()
1382        ),
1383      }
1384    }
1385  }
1386}
1387
1388impl_range_range_fxn_v!(Access2DRRVBB, access_2d_range_range_vbb, bool,  bool);
1389impl_range_range_fxn_v!(Access2DRRVBU, access_2d_range_range_vbu, bool,  usize);
1390impl_range_range_fxn_v!(Access2DRRVUU, access_2d_range_range_vuu, usize, usize);
1391impl_range_range_fxn_v!(Access2DRRVUB, access_2d_range_range_vub, usize, bool);
1392
1393fn matrix_access_range_range_fxn(source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1394  let arg = (source.clone(), ixes.as_slice());
1395               impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u8,   "u8")
1396  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u16,  "u16"))
1397  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u32,  "u32"))
1398  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u64,  "u64"))
1399  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u128, "u128"))
1400  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i8,   "i8"))
1401  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i16,  "i16"))
1402  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i32,  "i32"))
1403  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i64,  "i64"))
1404  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i128, "i128"))
1405  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, f32,  "f32"))
1406  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, f64,  "f64"))
1407  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, R64,  "rational"))
1408  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, C64,  "complex"))
1409  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, bool, "bool"))
1410  .or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, String, "string"))
1411  .map_err(|_| MechError::new(UnhandledFunctionArgumentIxesMono{
1412      arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()
1413    }, None).with_compiler_loc())
1414}
1415    
1416pub struct MatrixAccessRangeRange {}
1417impl NativeFunctionCompiler for MatrixAccessRangeRange {
1418  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1419    if arguments.len() <= 1 {
1420      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1421    }
1422    let source: Value = arguments[0].clone();
1423    let ixes = arguments.clone().split_off(1);
1424    match matrix_access_range_range_fxn(source.clone(), ixes.clone()) {
1425      Ok(fxn) => Ok(fxn),
1426      Err(_) => {
1427        match source {
1428          Value::MutableReference(source) => { matrix_access_range_range_fxn(source.borrow().clone(), ixes.clone()) },
1429          _ => Err(MechError::new(
1430            UnhandledFunctionArgumentIxesMono{arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()}, 
1431            None).with_compiler_loc()
1432          ),
1433        }
1434      }
1435    }
1436  }
1437}
1438
1439// x[:] -----------------------------------------------------------------------
1440
1441macro_rules! impl_access_all_match_arms {
1442  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1443    paste!{
1444      match $arg {
1445        $(
1446            $(
1447            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1448            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::IndexAll]) => {
1449              register_fxn_descriptor_inner!(Access1DAM4, $target_type, $value_string);
1450              Ok(Box::new(Access1DAM4  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1451            },
1452            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1453            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::IndexAll]) => {
1454              register_fxn_descriptor_inner!(Access1DAM3, $target_type, $value_string);
1455              Ok(Box::new(Access1DAM3  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1456            },
1457            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1458            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::IndexAll]) => {
1459              register_fxn_descriptor_inner!(Access1DAM2, $target_type, $value_string);
1460              Ok(Box::new(Access1DAM2  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1461            },
1462            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1463            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::IndexAll]) => {
1464              register_fxn_descriptor_inner!(Access1DAM3x2, $target_type, $value_string);
1465              Ok(Box::new(Access1DAM3x2{source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1466            },
1467            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1468            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::IndexAll]) => {
1469              register_fxn_descriptor_inner!(Access1DAM2x3, $target_type, $value_string);
1470              Ok(Box::new(Access1DAM2x3{source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1471            },
1472            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1473            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::IndexAll]) => {
1474              register_fxn_descriptor_inner!(Access1DAMD, $target_type, $value_string);
1475              Ok(Box::new(Access1DAMD  {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
1476            },
1477          )+
1478        )+
1479        (src, ix) => Err(MechError::new(
1480          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1481          None).with_compiler_loc()
1482        ),
1483      }
1484    }
1485  }
1486}
1487
1488fn impl_access_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1489  impl_access_match_arms!(Access1DA, all, (lhs_value, ixes.as_slice()))
1490}
1491
1492pub struct MatrixAccessAll {}
1493impl NativeFunctionCompiler for MatrixAccessAll {
1494  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1495    if arguments.len() <= 1 {
1496      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1497    }
1498    let ixes = arguments.clone().split_off(1);
1499    let mat = arguments[0].clone();
1500    match impl_access_all_fxn(mat.clone(), ixes.clone()) {
1501      Ok(fxn) => Ok(fxn),
1502      Err(_) => {
1503        match (mat,ixes) {
1504          (Value::MutableReference(lhs),rhs_value) => { impl_access_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1505          (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAll".to_string()}, None).with_compiler_loc()),
1506        }
1507      }
1508    }
1509  }
1510}
1511
1512// x[:,2] ---------------------------------------------------------------------
1513
1514macro_rules! impl_access_all_scalar_match_arms {
1515  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1516    paste!{
1517      match $arg {
1518        $(
1519            $(
1520            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1521            (Value::$matrix_kind(Matrix::Matrix4(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1522              register_fxn_descriptor_inner!(Access2DASM4, $target_type, $value_string);
1523              Ok(Box::new(Access2DASM4  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1524            },
1525            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1526            (Value::$matrix_kind(Matrix::Matrix3(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1527              register_fxn_descriptor_inner!(Access2DASM3, $target_type, $value_string);
1528              Ok(Box::new(Access2DASM3  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1529            },
1530            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1531            (Value::$matrix_kind(Matrix::Matrix2(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1532              register_fxn_descriptor_inner!(Access2DASM2, $target_type, $value_string);
1533              Ok(Box::new(Access2DASM2  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1534            },
1535            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1536            (Value::$matrix_kind(Matrix::Matrix2x3(input)),  [Value::IndexAll,Value::Index(ix)]) => {
1537              register_fxn_descriptor_inner!(Access2DASM2x3, $target_type, $value_string);
1538              Ok(Box::new(Access2DASM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1539            },
1540            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1541            (Value::$matrix_kind(Matrix::Matrix3x2(input)),  [Value::IndexAll,Value::Index(ix)]) => {
1542              register_fxn_descriptor_inner!(Access2DASM3x2, $target_type, $value_string);
1543              Ok(Box::new(Access2DASM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1544            },
1545            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1546            (Value::$matrix_kind(Matrix::DMatrix(input)),    [Value::IndexAll,Value::Index(ix)]) => {
1547              register_fxn_descriptor_inner!(Access2DASMD, $target_type, $value_string);
1548              Ok(Box::new(Access2DASMD  {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
1549            },
1550          )+
1551        )+
1552        (src, ix) => Err(MechError::new(
1553          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1554          None).with_compiler_loc()
1555        ),
1556      }
1557    }
1558  }
1559}
1560
1561fn impl_access_all_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1562  impl_access_match_arms!(Access2DAS, all_scalar, (lhs_value, ixes.as_slice()))
1563}
1564
1565pub struct MatrixAccessAllScalar {}
1566impl NativeFunctionCompiler for MatrixAccessAllScalar {
1567  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1568    if arguments.len() <= 2 {
1569      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1570    }
1571    let ixes = arguments.clone().split_off(1);
1572    let mat = arguments[0].clone();
1573    match impl_access_all_scalar_fxn(mat.clone(), ixes.clone()) {
1574      Ok(fxn) => Ok(fxn),
1575      Err(_) => {
1576        match (mat,ixes) {
1577          (Value::MutableReference(lhs),rhs_value) => { impl_access_all_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1578          (src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllScalar".to_string()}, None).with_compiler_loc()),
1579        }
1580      }
1581    }
1582  }
1583}
1584
1585// x[2,:] ---------------------------------------------------------------------
1586
1587macro_rules! impl_access_scalar_all_match_arms {
1588  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1589    paste!{
1590      match $arg {
1591        $(
1592            $(
1593            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "row_vector4"))]
1594            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix),Value::IndexAll]) => {
1595              register_fxn_descriptor_inner!(Access2DSAM4, $target_type, $value_string);
1596              Ok(Box::new(Access2DSAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector4::from_element($default)) }))
1597            },
1598            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "row_vector3"))]
1599            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix),Value::IndexAll]) => {
1600              register_fxn_descriptor_inner!(Access2DSAM3, $target_type, $value_string);
1601              Ok(Box::new(Access2DSAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector3::from_element($default)) }))
1602            },
1603            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "row_vector2"))]
1604            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix),Value::IndexAll]) => {
1605              register_fxn_descriptor_inner!(Access2DSAM2, $target_type, $value_string);
1606              Ok(Box::new(Access2DSAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector2::from_element($default)) }))
1607            },
1608            #[cfg(all(feature = $value_string, feature = "matrix1", feature = "matrix1"))]
1609            (Value::$matrix_kind(Matrix::Matrix1(input)), [Value::Index(ix),Value::IndexAll]) => {
1610              register_fxn_descriptor_inner!(Access2DSAM1, $target_type, $value_string);
1611              Ok(Box::new(Access2DSAM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(Matrix1::from_element($default)) }))
1612            },
1613            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "row_vector2"))]
1614            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix),Value::IndexAll]) => {
1615              register_fxn_descriptor_inner!(Access2DSAM3x2, $target_type, $value_string);
1616              Ok(Box::new(Access2DSAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector2::from_element($default)) }))
1617            },
1618            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "row_vector3"))]
1619            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix),Value::IndexAll]) => {
1620              register_fxn_descriptor_inner!(Access2DSAM2x3, $target_type, $value_string);
1621              Ok(Box::new(Access2DSAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector3::from_element($default)) }))
1622            },
1623            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "row_vectord"))]
1624            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix),Value::IndexAll]) => {
1625              register_fxn_descriptor_inner!(Access2DSAMD, $target_type, $value_string);
1626              Ok(Box::new(Access2DSAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowDVector::from_element(input.borrow().ncols(),$default)) }))
1627            },
1628          )+
1629        )+
1630        (src, ix) => Err(MechError::new(
1631          UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1632          None).with_compiler_loc()
1633        ),
1634      }
1635    }
1636  }
1637}
1638
1639fn impl_access_scalar_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1640 impl_access_match_arms!(Access2DSA, scalar_all, (lhs_value, ixes.as_slice()))
1641}
1642
1643pub struct MatrixAccessScalarAll {}
1644impl NativeFunctionCompiler for MatrixAccessScalarAll {
1645  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1646    if arguments.len() <= 2 {
1647      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1648    }
1649    let ixes = arguments.clone().split_off(1);
1650    let mat = arguments[0].clone();
1651    match impl_access_scalar_all_fxn(mat.clone(), ixes.clone()) {
1652      Ok(fxn) => Ok(fxn),
1653      Err(_) => {
1654        match (mat,ixes) {
1655          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1656          (mat, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (mat.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarAll".to_string()}, None).with_compiler_loc()),
1657        }
1658      }
1659    }
1660  }
1661}
1662
1663// x[:,1..3] ---------------------------------------------------------------------
1664
1665macro_rules! assign_2d_all_range_v {
1666  ($source:expr, $ix:expr, $sink:expr) => {
1667    {
1668      let mut sink_col_ix = 0;
1669      for i in 0..(*$ix).len() {
1670        let col_ix = $ix[i] - 1;
1671        let mut sink_col = ($sink).column_mut(sink_col_ix);
1672        let src_col = ($source).column(col_ix);
1673        for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
1674          *dst = src.clone();
1675        }
1676        sink_col_ix += 1;
1677      }
1678    }
1679  };}
1680
1681macro_rules! assign_2d_all_range_vb {
1682  ($source:expr, $ix:expr, $sink:expr) => {
1683    {
1684      let mut sink_col_ix = 0;
1685      for i in 0..(*$source).ncols() {
1686        if $ix[i] == true {
1687          let mut sink_col = ($sink).column_mut(sink_col_ix);
1688          let src_col = ($source).column(i);
1689          for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
1690            *dst = src.clone();
1691          }
1692          sink_col_ix += 1;
1693        }
1694      }
1695    }
1696  };}
1697
1698macro_rules! impl_access_all_range_arms {
1699  ($fxn_name:ident, $shape:tt, $arg:expr, $value_kind:ident, $value_string:tt) => {
1700    paste!{
1701      match $arg {
1702        // All Vector
1703        #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "vectord"))]
1704        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixIndex(Matrix::DVector(ix))]) if source.borrow().nrows() == 1 => {
1705          register_assign!([<$fxn_name V>], $value_kind, $value_string, RowDVector, $shape, DVector);
1706          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() })))
1707        },
1708        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
1709        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixIndex(Matrix::DVector(ix))]) => {
1710          register_assign!([<$fxn_name V>], $value_kind, $value_string, DMatrix, $shape, DVector);
1711          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() })))
1712        },
1713        // All Bool Vector
1714        #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "vectord"))]
1715        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) if source.borrow().nrows() == 1 => {
1716          let cols = ix.borrow().iter().filter(|&&b| b).count();
1717          register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, RowDVector, $shape, DVector);
1718          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() })))
1719        },
1720        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing", feature = "vectord"))]
1721        (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 => {
1722          register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, DVector, $shape, DVector);
1723          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() })))
1724        },
1725        #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing", feature = "vectord"))]
1726        (Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) => {
1727          let cols = ix.borrow().iter().filter(|&&b| b).count();
1728          register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, DMatrix, $shape, DVector);
1729          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() })))
1730        },
1731        (sink, ix) => {
1732          Err(MechError::new(
1733            UnhandledFunctionArgumentIxesMono{arg: (sink.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()}, 
1734            None).with_compiler_loc()
1735          )
1736        }
1737      }
1738    }
1739  }
1740}
1741
1742impl_all_fxn_v!(Access2DARV,  assign_2d_all_range_v,  usize);
1743impl_all_fxn_v!(Access2DARVB, assign_2d_all_range_vb, bool);
1744
1745fn matrix_access_all_range_fxn(source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1746  let arg = (source.clone(), ixes.as_slice());
1747               impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u8,   "u8")
1748  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u16,  "u16"))
1749  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u32,  "u32"))
1750  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u64,  "u64"))
1751  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u128, "u128"))
1752  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i8,   "i8"))
1753  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i16,  "i16"))
1754  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i32,  "i32"))
1755  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i64,  "i64"))
1756  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i128, "i128"))
1757  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, f32,  "f32"))
1758  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, f64,  "f64"))
1759  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, R64,  "rational"))
1760  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, C64,  "complex"))
1761  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, bool, "bool"))
1762  .or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, String, "string"))
1763  .map_err(|_| MechError::new(UnhandledFunctionArgumentIxesMono{
1764      arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllRange".to_string()
1765    }, None).with_compiler_loc())
1766}
1767    
1768pub struct MatrixAccessAllRange {}
1769impl NativeFunctionCompiler for MatrixAccessAllRange {
1770  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1771    if arguments.len() <= 1 {
1772      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1773    }
1774    let source: Value = arguments[0].clone();
1775    let ixes = arguments.clone().split_off(1);
1776    match matrix_access_all_range_fxn(source.clone(), ixes.clone()) {
1777      Ok(fxn) => Ok(fxn),
1778      Err(_) => {
1779        match source {
1780          Value::MutableReference(source) => { matrix_access_all_range_fxn(source.borrow().clone(), ixes.clone()) },
1781          x => Err(MechError::new(
1782            UnhandledFunctionArgumentIxesMono{arg: (x.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllRange".to_string()}, 
1783            None).with_compiler_loc()
1784          ),
1785        }
1786      }
1787    }
1788  }
1789}
1790
1791// x[1..3,:] ---------------------------------------------------------------------
1792
1793macro_rules! impl_access_range_all_match_arms {
1794  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1795    paste!{
1796      match $arg {
1797        $(
1798          $(
1799            // Vector All
1800            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1801            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1802              register_fxn_descriptor_inner!(Access2DVDAM4, $target_type, $value_string);
1803              Ok(Box::new(Access2DVDAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1804            },
1805            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1806            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1807              register_fxn_descriptor_inner!(Access2DVDAM3, $target_type, $value_string);
1808              Ok(Box::new(Access2DVDAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1809            },
1810            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1811            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1812              register_fxn_descriptor_inner!(Access2DVDAM2, $target_type, $value_string);
1813              Ok(Box::new(Access2DVDAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1814            },
1815            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1816            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1817              register_fxn_descriptor_inner!(Access2DVDAM3x2, $target_type, $value_string);
1818              Ok(Box::new(Access2DVDAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1819            },
1820            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1821            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1822              register_fxn_descriptor_inner!(Access2DVDAM2x3, $target_type, $value_string);
1823              Ok(Box::new(Access2DVDAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1824            },
1825            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1826            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
1827              register_fxn_descriptor_inner!(Access2DVDAMD, $target_type, $value_string);
1828              Ok(Box::new(Access2DVDAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1829            },
1830            // Bool Vector All
1831            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1832            (Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1833              register_fxn_descriptor_inner!(Access2DVDbAM4, $target_type, $value_string);
1834              Ok(Box::new(Access2DVDbAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1835            },
1836            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1837            (Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1838              register_fxn_descriptor_inner!(Access2DVDbAM3, $target_type, $value_string);
1839              Ok(Box::new(Access2DVDbAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1840            },
1841            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1842            (Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1843              register_fxn_descriptor_inner!(Access2DVDbAM2, $target_type, $value_string);
1844              Ok(Box::new(Access2DVDbAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1845            },
1846            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1847            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1848              register_fxn_descriptor_inner!(Access2DVDbAM3x2, $target_type, $value_string);
1849              Ok(Box::new(Access2DVDbAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1850            },
1851            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
1852            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1853              register_fxn_descriptor_inner!(Access2DVDbAM2x3, $target_type, $value_string);
1854              Ok(Box::new(Access2DVDbAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1855            },
1856            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
1857            (Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
1858              register_fxn_descriptor_inner!(Access2DVDbAMD, $target_type, $value_string);
1859              Ok(Box::new(Access2DVDbAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
1860            },
1861          )+
1862        )+
1863        (src, ixes) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeAll".to_string()}, None).with_compiler_loc()),
1864      }
1865    }
1866  }
1867}
1868
1869fn impl_access_range_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1870  impl_access_match_arms!(Access2DRA, range_all, (lhs_value, ixes.as_slice()))
1871}
1872
1873  pub struct MatrixAccessRangeAll {}
1874impl NativeFunctionCompiler for MatrixAccessRangeAll {
1875  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1876    if arguments.len() <= 2 {
1877      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1878    }
1879    let ixes = arguments.clone().split_off(1);
1880    let mat = arguments[0].clone();
1881    match impl_access_range_all_fxn(mat.clone(), ixes.clone()) {
1882      Ok(fxn) => Ok(fxn),
1883      Err(_) => {
1884        match (mat.clone(),ixes.clone()) {
1885          (Value::MutableReference(lhs),rhs_value) => { impl_access_range_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1886          (src, ixes) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeAll".to_string()}, None).with_compiler_loc()),
1887        }
1888      }
1889    }
1890  }
1891}
1892
1893// x[1..3,2] ---------------------------------------------------------------------
1894
1895macro_rules! impl_access_range_scalar_match_arms {
1896  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1897    paste!{
1898      match $arg {
1899        $(
1900            $(
1901            // Vector Scalar
1902            #[cfg(all(feature = $value_string, feature = "matrix4"))]
1903            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1904              register_fxn_descriptor_inner!(Access2DVDSM4, $target_type, $value_string);
1905              Ok(Box::new(Access2DVDSM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1906            },
1907            #[cfg(all(feature = $value_string, feature = "matrix3"))]
1908            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1909              register_fxn_descriptor_inner!(Access2DVDSM3, $target_type, $value_string);
1910              Ok(Box::new(Access2DVDSM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1911            },
1912            #[cfg(all(feature = $value_string, feature = "matrix2"))]
1913            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1914              register_fxn_descriptor_inner!(Access2DVDSM2, $target_type, $value_string);
1915              Ok(Box::new(Access2DVDSM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1916            },
1917            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
1918            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1919              register_fxn_descriptor_inner!(Access2DVDSM2x3, $target_type, $value_string);
1920              Ok(Box::new(Access2DVDSM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1921            },
1922            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
1923            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1924              register_fxn_descriptor_inner!(Access2DVDSM3x2, $target_type, $value_string);
1925              Ok(Box::new(Access2DVDSM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1926            },
1927            #[cfg(all(feature = $value_string, feature = "matrixd"))]
1928            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1929              register_fxn_descriptor_inner!(Access2DVDSMD, $target_type, $value_string);
1930              Ok(Box::new(Access2DVDSMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1931            },
1932            // Bool Vector Scalar
1933            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
1934            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1935              register_fxn_descriptor_inner!(Access2DVDbSM4, $target_type, $value_string);
1936              Ok(Box::new(Access2DVDbSM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1937            },
1938            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
1939            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1940              register_fxn_descriptor_inner!(Access2DVDbSM3, $target_type, $value_string);
1941              Ok(Box::new(Access2DVDbSM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1942            },
1943            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
1944            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1945              register_fxn_descriptor_inner!(Access2DVDbSM2, $target_type, $value_string);
1946              Ok(Box::new(Access2DVDbSM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1947            },
1948            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
1949            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1950              register_fxn_descriptor_inner!(Access2DVDbSM2x3, $target_type, $value_string);
1951              Ok(Box::new(Access2DVDbSM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1952            },
1953            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
1954            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1955              register_fxn_descriptor_inner!(Access2DVDbSM3x2, $target_type, $value_string);
1956              Ok(Box::new(Access2DVDbSM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1957            },
1958            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
1959            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
1960              register_fxn_descriptor_inner!(Access2DVDbSMD, $target_type, $value_string);
1961              Ok(Box::new(Access2DVDbSMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
1962            },)+
1963        )+
1964        (src, ixes) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()}, None).with_compiler_loc()),
1965      }
1966    }
1967  }
1968}
1969
1970fn impl_access_range_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1971  impl_access_match_arms!(Access2DRS, range_scalar, (lhs_value, ixes.as_slice()))
1972}
1973
1974pub struct MatrixAccessRangeScalar {}
1975impl NativeFunctionCompiler for MatrixAccessRangeScalar {
1976  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1977    if arguments.len() <= 2 {
1978      return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1979    }
1980    let ixes = arguments.clone().split_off(1);
1981    let mat = arguments[0].clone();
1982    match impl_access_range_scalar_fxn(mat.clone(), ixes.clone()) {
1983      Ok(fxn) => Ok(fxn),
1984      Err(_) => {
1985        match (mat,ixes) {
1986          (Value::MutableReference(lhs),rhs_value) => { impl_access_range_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
1987          (src,ixs) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ixs.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeScalar".to_string() }, None).with_compiler_loc()),
1988        }
1989      }
1990    }
1991  }
1992}
1993
1994// x[2,1..3] ---------------------------------------------------------------------
1995
1996macro_rules! impl_access_scalar_range_match_arms {
1997  ($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
1998    paste!{
1999      match $arg {
2000        $(
2001          $(
2002            // Scalar Vector 
2003            #[cfg(all(feature = $value_string, feature = "matrix4"))]
2004            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
2005              register_fxn_descriptor_inner!(Access2DSVDM4, $target_type, $value_string);
2006              Ok(Box::new(Access2DSVDM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2007            },
2008            #[cfg(all(feature = $value_string, feature = "matrix3"))]
2009            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
2010              register_fxn_descriptor_inner!(Access2DSVDM3, $target_type, $value_string);
2011              Ok(Box::new(Access2DSVDM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2012            },
2013            #[cfg(all(feature = $value_string, feature = "matrix2"))]
2014            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
2015              register_fxn_descriptor_inner!(Access2DSVDM2, $target_type, $value_string);
2016              Ok(Box::new(Access2DSVDM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2017            },
2018            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
2019            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
2020              register_fxn_descriptor_inner!(Access2DSVDM3x2, $target_type, $value_string);
2021              Ok(Box::new(Access2DSVDM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2022            },
2023            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
2024            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
2025              register_fxn_descriptor_inner!(Access2DSVDM2x3, $target_type, $value_string);
2026              Ok(Box::new(Access2DSVDM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2027            },
2028            #[cfg(all(feature = $value_string, feature = "matrixd"))]
2029            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
2030              register_fxn_descriptor_inner!(Access2DSVDMD, $target_type, $value_string);
2031              Ok(Box::new(Access2DSVDMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2032            },
2033            // Bool Scalar Vector
2034            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
2035            (Value::$matrix_kind(Matrix::Matrix4(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2036              register_fxn_descriptor_inner!(Access2DSVDbM4, $target_type, $value_string);
2037              Ok(Box::new(Access2DSVDbM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2038            },
2039            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
2040            (Value::$matrix_kind(Matrix::Matrix3(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2041              register_fxn_descriptor_inner!(Access2DSVDbM3, $target_type, $value_string);
2042              Ok(Box::new(Access2DSVDbM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2043            },
2044            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
2045            (Value::$matrix_kind(Matrix::Matrix2(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2046              register_fxn_descriptor_inner!(Access2DSVDbM2, $target_type, $value_string);
2047              Ok(Box::new(Access2DSVDbM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2048            },
2049            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
2050            (Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2051              register_fxn_descriptor_inner!(Access2DSVDbM3x2, $target_type, $value_string);
2052              Ok(Box::new(Access2DSVDbM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2053            },
2054            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
2055            (Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2056              register_fxn_descriptor_inner!(Access2DSVDbM2x3, $target_type, $value_string);
2057              Ok(Box::new(Access2DSVDbM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2058            },
2059            #[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
2060            (Value::$matrix_kind(Matrix::DMatrix(input)),   [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
2061              register_fxn_descriptor_inner!(Access2DSVDbMD, $target_type, $value_string);
2062              Ok(Box::new(Access2DSVDbMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
2063            },)+
2064        )+
2065        (src,ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{ arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
2066      }
2067    }
2068  }
2069}
2070
2071fn impl_access_scalar_range_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
2072  impl_access_match_arms!(Access2DSR, scalar_range, (lhs_value, ixes.as_slice()))
2073}
2074
2075pub struct MatrixAccessScalarRange {}
2076
2077impl NativeFunctionCompiler for MatrixAccessScalarRange {
2078  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
2079    if arguments.len() <= 2 {
2080      return Err(MechError::new(IncorrectNumberOfArguments{expected: 1, found: arguments.len()}, None).with_compiler_loc());
2081    }
2082    let ixes = arguments.clone().split_off(1);
2083    let mat = arguments[0].clone();
2084    match impl_access_scalar_range_fxn(mat.clone(), ixes.clone()) {
2085      Ok(fxn) => Ok(fxn),
2086      Err(_) => {
2087        match (mat.clone(),ixes.clone()) {
2088          (Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_range_fxn(lhs.borrow().clone(), rhs_value.clone()) }
2089          x => Err(MechError::new(UnhandledFunctionArgumentIxesMono{ arg: (mat.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarRange".to_string() }, None).with_compiler_loc()),
2090        }
2091      }
2092    }
2093  }
2094}