mech_core/
stdlib.rs

1pub use crate::*;
2
3// The Standard Libray
4// ----------------------------------------------------------------------------
5
6// These macros are used by various libraries to generate function impl and
7// match arms. They're gated on feature flags so although there's a lot of
8// code here to account for all the different combinations, but only
9// the relevant code will be compiled in any given build.
10
11#[macro_export]
12macro_rules! compile_unop {
13  ($out:expr, $arg:expr, $ctx:ident, $feature_flag:expr) => {
14    // allocate three registers as an array
15    let mut registers = [0,0];
16
17    // Compile out
18    let out_addr = $out.addr();
19    let out_reg = $ctx.alloc_register_for_ptr(out_addr);
20    let out_borrow = $out.borrow();
21    let out_const_id = out_borrow.compile_const($ctx).unwrap();
22    $ctx.emit_const_load(out_reg, out_const_id);
23    registers[0] = out_reg;
24    
25    // Compile arg
26    let arg_addr = $arg.addr();
27    let arg_reg = $ctx.alloc_register_for_ptr(arg_addr);
28    let arg_borrow = $arg.borrow();
29    let arg_const_id = arg_borrow.compile_const($ctx).unwrap();
30    $ctx.emit_const_load(arg_reg, arg_const_id);
31    registers[1] = arg_reg;
32  
33    $ctx.features.insert($feature_flag);
34
35    // Emit the operation
36    $ctx.emit_unop(
37      hash_str(stringify!($struct_name)),
38      registers[0],
39      registers[1],
40    );
41
42    return Ok(registers[0]);
43  };
44}
45
46#[macro_export]
47macro_rules! compile_binop {
48  ($out:expr, $arg1:expr, $arg2:expr, $ctx:ident, $feature_flag:expr) => {
49    // allocate three registers as an array
50    let mut registers = [0,0,0];
51
52    // Compile out
53    let out_addr = $out.addr();
54    let out_reg = $ctx.alloc_register_for_ptr(out_addr);
55    let out_borrow = $out.borrow();
56    let out_const_id = out_borrow.compile_const($ctx).unwrap();
57    $ctx.emit_const_load(out_reg, out_const_id);
58    registers[0] = out_reg;
59
60    // Compile lhs
61    let lhs_addr = $arg1.addr();
62    let lhs_reg = $ctx.alloc_register_for_ptr(lhs_addr);
63    let lhs_borrow = $arg1.borrow();
64    let lhs_const_id = lhs_borrow.compile_const($ctx).unwrap();
65    $ctx.emit_const_load(lhs_reg, lhs_const_id);
66    registers[1] = lhs_reg;
67
68    // Compile rhs
69    let rhs_addr = $arg2.addr();
70    let rhs_reg = $ctx.alloc_register_for_ptr(rhs_addr);
71    let rhs_borrow = $arg2.borrow();
72    let rhs_const_id = rhs_borrow.compile_const($ctx).unwrap();
73    $ctx.emit_const_load(rhs_reg, rhs_const_id);
74    registers[2] = rhs_reg;
75
76    $ctx.features.insert($feature_flag);
77
78    // Emit the operation
79    $ctx.emit_binop(
80      hash_str(stringify!($struct_name)),
81      registers[0],
82      registers[1],
83      registers[2],
84    );
85
86    return Ok(registers[0])
87  };
88}
89
90
91#[macro_export]
92macro_rules! impl_binop {
93  ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident, $feature_flag:expr) => {
94    #[derive(Debug)]
95    pub struct $struct_name<T> {
96      pub lhs: Ref<$arg1_type>,
97      pub rhs: Ref<$arg2_type>,
98      pub out: Ref<$out_type>,
99    }
100    impl<T> MechFunctionImpl for $struct_name<T>
101    where
102      T: Copy + Debug + Display + Clone + Sync + Send + 'static + 
103      PartialEq + PartialOrd +
104      Add<Output = T> + AddAssign +
105      Sub<Output = T> + SubAssign +
106      Mul<Output = T> + MulAssign +
107      Div<Output = T> + DivAssign +
108      Zero + One,
109      Ref<$out_type>: ToValue
110    {
111      fn solve(&self) {
112          let lhs_ptr = self.lhs.as_ptr();
113          let rhs_ptr = self.rhs.as_ptr();
114          let out_ptr = self.out.as_mut_ptr();
115          $op!(lhs_ptr,rhs_ptr,out_ptr);
116      }
117      fn out(&self) -> Value { self.out.to_value() }
118      fn to_string(&self) -> String { format!("{:#?}", self) }
119    }   
120    #[cfg(feature = "compiler")]
121    impl<T> MechFunctionCompiler for $struct_name<T> 
122    where
123      T: ConstElem + CompileConst
124    {
125      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
126        compile_binop!(self.out, self.lhs, self.rhs, ctx, $feature_flag);
127      }
128    }};}
129
130#[macro_export]  
131macro_rules! impl_unop {
132  ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident, $feature_flag:expr) => {
133    #[derive(Debug)]
134    struct $struct_name {
135      arg: Ref<$arg_type>,
136      out: Ref<$out_type>,
137    }
138    impl MechFunctionImpl for $struct_name {
139      fn solve(&self) {
140        let arg_ptr = self.arg.as_ptr();
141        let out_ptr = self.out.as_mut_ptr();
142        $op!(arg_ptr,out_ptr);
143      }
144      fn out(&self) -> Value { self.out.to_value() }
145      fn to_string(&self) -> String { format!("{:#?}", self) }
146    }
147    #[cfg(feature = "compiler")]
148    impl MechFunctionCompiler for $struct_name {
149      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
150        compile_unop!(self.out, self.arg, ctx, $feature_flag);
151      }
152    }};} 
153
154#[macro_export]
155macro_rules! impl_fxns {
156  ($lib:ident, $in:ident, $out:ident, $op:ident) => {
157    paste!{
158      // Scalar
159      $op!([<$lib SS>], $in, $in, $out, [<$lib:lower _op>], FeatureFlag::Builtin(FeatureKind::$lib));
160      // Scalar Matrix
161      #[cfg(feature = "matrix1")]
162      $op!([<$lib SM1>], $in, Matrix1<$in>, Matrix1<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
163      #[cfg(feature = "matrix2")]
164      $op!([<$lib SM2>], $in, Matrix2<$in>, Matrix2<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
165      #[cfg(feature = "matrix3")]
166      $op!([<$lib SM3>], $in, Matrix3<$in>, Matrix3<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
167      
168      #[cfg(feature = "matrix4")]
169      $op!([<$lib SM4>], $in, Matrix4<$in>, Matrix4<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
170      #[cfg(feature = "matrix2x3")]
171      $op!([<$lib SM2x3>], $in, Matrix2x3<$in>, Matrix2x3<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
172      #[cfg(feature = "matrix3x2")]
173      $op!([<$lib SM3x2>], $in, Matrix3x2<$in>, Matrix3x2<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
174      #[cfg(feature = "matrixd")]
175      $op!([<$lib SMD>], $in, DMatrix<$in>, DMatrix<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
176      // Scalar Row
177      #[cfg(feature = "row_vector2")]
178      $op!([<$lib SR2>], $in, RowVector2<$in>, RowVector2<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
179      #[cfg(feature = "row_vector3")]
180      $op!([<$lib SR3>], $in, RowVector3<$in>, RowVector3<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
181      #[cfg(feature = "row_vector4")]
182      $op!([<$lib SR4>], $in, RowVector4<$in>, RowVector4<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
183      #[cfg(feature = "row_vectord")]
184      $op!([<$lib SRD>], $in, RowDVector<$in>, RowDVector<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
185      // Scalar Vector
186      #[cfg(feature = "vector2")]
187      $op!([<$lib SV2>], $in, Vector2<$in>, Vector2<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
188      #[cfg(feature = "vector3")]
189      $op!([<$lib SV3>], $in, Vector3<$in>, Vector3<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
190      #[cfg(feature = "vector4")]
191      $op!([<$lib SV4>], $in, Vector4<$in>, Vector4<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
192      #[cfg(feature = "vectord")]
193      $op!([<$lib SVD>], $in, DVector<$in>, DVector<$out>,[<$lib:lower _scalar_rhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
194      // Matrix Scalar
195      #[cfg(feature = "matrix1")]
196      $op!([<$lib M1S>], Matrix1<$in>, $in, Matrix1<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
197      #[cfg(feature = "matrix2")]
198      $op!([<$lib M2S>], Matrix2<$in>, $in, Matrix2<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
199      #[cfg(feature = "matrix3")]
200      $op!([<$lib M3S>], Matrix3<$in>, $in, Matrix3<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
201      #[cfg(feature = "matrix4")]
202      $op!([<$lib M4S>], Matrix4<$in>, $in, Matrix4<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
203      #[cfg(feature = "matrix2x3")]
204      $op!([<$lib M2x3S>], Matrix2x3<$in>, $in, Matrix2x3<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
205      #[cfg(feature = "matrix3x2")]
206      $op!([<$lib M3x2S>], Matrix3x2<$in>, $in, Matrix3x2<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
207      #[cfg(feature = "matrixd")]
208      $op!([<$lib MDS>], DMatrix<$in>, $in, DMatrix<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
209      // Row Scalar
210      #[cfg(feature = "row_vector2")]
211      $op!([<$lib R2S>], RowVector2<$in>, $in, RowVector2<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
212      #[cfg(feature = "row_vector3")]
213      $op!([<$lib R3S>], RowVector3<$in>, $in, RowVector3<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
214      #[cfg(feature = "row_vector4")]
215      $op!([<$lib R4S>], RowVector4<$in>, $in, RowVector4<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
216      #[cfg(feature = "row_vectord")]
217      $op!([<$lib RDS>], RowDVector<$in>, $in, RowDVector<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
218      // Vector Scalar
219      #[cfg(feature = "vector2")]
220      $op!([<$lib V2S>], Vector2<$in>, $in, Vector2<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
221      #[cfg(feature = "vector3")]
222      $op!([<$lib V3S>], Vector3<$in>, $in, Vector3<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
223      #[cfg(feature = "vector4")]
224      $op!([<$lib V4S>], Vector4<$in>, $in, Vector4<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
225      #[cfg(feature = "vectord")]
226      $op!([<$lib VDS>], DVector<$in>, $in, DVector<$out>,[<$lib:lower _scalar_lhs_op>], FeatureFlag::Builtin(FeatureKind::$lib));
227      // Matrix Matrix
228      #[cfg(feature = "matrix1")]
229      $op!([<$lib M1M1>], Matrix1<$in>, Matrix1<$in>, Matrix1<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
230      #[cfg(feature = "matrix2")]
231      $op!([<$lib M2M2>], Matrix2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
232      #[cfg(feature = "matrix3")]
233      $op!([<$lib M3M3>], Matrix3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
234      #[cfg(feature = "matrix4")]
235      $op!([<$lib M4M4>], Matrix4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
236      #[cfg(feature = "matrix2x3")]
237      $op!([<$lib M2x3M2x3>], Matrix2x3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
238      #[cfg(feature = "matrix3x2")]
239      $op!([<$lib M3x2M3x2>], Matrix3x2<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
240      #[cfg(feature = "matrixd")]
241      $op!([<$lib MDMD>], DMatrix<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
242      // Matrix Vector
243      #[cfg(all(feature = "matrix2", feature = "vector2"))]
244      $op!([<$lib M2V2>], Matrix2<$in>, Vector2<$in>, Matrix2<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
245      #[cfg(all(feature = "matrix3", feature = "vector3"))]
246      $op!([<$lib M3V3>], Matrix3<$in>, Vector3<$in>, Matrix3<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
247      #[cfg(all(feature = "matrix4", feature = "vector4"))]
248      $op!([<$lib M4V4>], Matrix4<$in>, Vector4<$in>, Matrix4<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
249      #[cfg(all(feature = "matrix2x3", feature = "vector2"))]
250      $op!([<$lib M2x3V2>], Matrix2x3<$in>, Vector2<$in>, Matrix2x3<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
251      #[cfg(all(feature = "matrix3x2", feature = "vector3"))]
252      $op!([<$lib M3x2V3>], Matrix3x2<$in>, Vector3<$in>, Matrix3x2<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
253      #[cfg(all(feature = "matrixd", feature = "vectord"))]
254      $op!([<$lib MDVD>], DMatrix<$in>, DVector<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
255      #[cfg(all(feature = "matrixd", feature = "vector2"))]
256      $op!([<$lib MDV2>], DMatrix<$in>, Vector2<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
257      #[cfg(all(feature = "matrixd", feature = "vector3"))]
258      $op!([<$lib MDV3>], DMatrix<$in>, Vector3<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
259      #[cfg(all(feature = "matrixd", feature = "vector4"))]
260      $op!([<$lib MDV4>], DMatrix<$in>, Vector4<$in>, DMatrix<$out>, [<$lib:lower _mat_vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
261      // Vector Matrix
262      #[cfg(all(feature = "vector2", feature = "matrix2"))]
263      $op!([<$lib V2M2>], Vector2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
264      #[cfg(all(feature = "vector3", feature = "matrix3"))]
265      $op!([<$lib V3M3>], Vector3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
266      #[cfg(all(feature = "vector4", feature = "matrix4"))]
267      $op!([<$lib V4M4>], Vector4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
268      #[cfg(all(feature = "vector2", feature = "matrix2x3"))]
269      $op!([<$lib V2M2x3>], Vector2<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
270      #[cfg(all(feature = "vector3", feature = "matrix3x2"))]
271      $op!([<$lib V3M3x2>], Vector3<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
272      #[cfg(all(feature = "vectord", feature = "matrixd"))]
273      $op!([<$lib VDMD>], DVector<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
274      #[cfg(all(feature = "vector2", feature = "matrixd"))]
275      $op!([<$lib V2MD>], Vector2<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
276      #[cfg(all(feature = "vector3", feature = "matrixd"))]
277      $op!([<$lib V3MD>], Vector3<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
278      #[cfg(all(feature = "vector4", feature = "matrixd"))]
279      $op!([<$lib V4MD>], Vector4<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
280      // Matrix Row
281      #[cfg(all(feature = "matrix2", feature = "row_vector2"))]
282      $op!([<$lib M2R2>], Matrix2<$in>, RowVector2<$in>, Matrix2<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib)); 
283      #[cfg(all(feature = "matrix3", feature = "row_vector3"))]
284      $op!([<$lib M3R3>], Matrix3<$in>, RowVector3<$in>, Matrix3<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
285      #[cfg(all(feature = "matrix4", feature = "row_vector4"))]
286      $op!([<$lib M4R4>], Matrix4<$in>, RowVector4<$in>, Matrix4<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
287      #[cfg(all(feature = "matrix2x3", feature = "row_vector3"))]
288      $op!([<$lib M2x3R3>], Matrix2x3<$in>, RowVector3<$in>, Matrix2x3<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
289      #[cfg(all(feature = "matrix3x2", feature = "row_vector2"))]
290      $op!([<$lib M3x2R2>], Matrix3x2<$in>, RowVector2<$in>, Matrix3x2<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
291      #[cfg(all(feature = "matrixd", feature = "row_vectord"))]
292      $op!([<$lib MDRD>], DMatrix<$in>, RowDVector<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
293      #[cfg(all(feature = "matrixd", feature = "row_vector2"))]
294      $op!([<$lib MDR2>], DMatrix<$in>, RowVector2<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
295      #[cfg(all(feature = "matrixd", feature = "row_vector3"))]
296      $op!([<$lib MDR3>], DMatrix<$in>, RowVector3<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib));
297      #[cfg(all(feature = "matrixd", feature = "row_vector4"))]
298      $op!([<$lib MDR4>], DMatrix<$in>, RowVector4<$in>, DMatrix<$out>, [<$lib:lower _mat_row_op>], FeatureFlag::Builtin(FeatureKind::$lib)); 
299      // Row Matrix
300      #[cfg(all(feature = "row_vector2", feature = "matrix2"))]
301      $op!([<$lib R2M2>], RowVector2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib)); 
302      #[cfg(all(feature = "row_vector3", feature = "matrix3"))]
303      $op!([<$lib R3M3>], RowVector3<$in>, Matrix3<$in>, Matrix3<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
304      #[cfg(all(feature = "row_vector4", feature = "matrix4"))]
305      $op!([<$lib R4M4>], RowVector4<$in>, Matrix4<$in>, Matrix4<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
306      #[cfg(all(feature = "row_vector3", feature = "matrix2x3"))]
307      $op!([<$lib R3M2x3>], RowVector3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
308      #[cfg(all(feature = "row_vector2", feature = "matrix3x2"))]
309      $op!([<$lib R2M3x2>], RowVector2<$in>, Matrix3x2<$in>, Matrix3x2<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
310      #[cfg(all(feature = "row_vectord", feature = "matrixd"))]
311      $op!([<$lib RDMD>], RowDVector<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
312      #[cfg(all(feature = "row_vector2", feature = "matrixd"))]
313      $op!([<$lib R2MD>], RowVector2<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
314      #[cfg(all(feature = "row_vector3", feature = "matrixd"))]
315      $op!([<$lib R3MD>], RowVector3<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
316      #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
317      $op!([<$lib R4MD>], RowVector4<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _row_mat_op>], FeatureFlag::Builtin(FeatureKind::$lib));
318      // Row Row
319      #[cfg(feature = "row_vector2")]
320      $op!([<$lib R2R2>], RowVector2<$in>, RowVector2<$in>, RowVector2<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
321      #[cfg(feature = "row_vector3")]
322      $op!([<$lib R3R3>], RowVector3<$in>, RowVector3<$in>, RowVector3<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
323      #[cfg(feature = "row_vector4")]
324      $op!([<$lib R4R4>], RowVector4<$in>, RowVector4<$in>, RowVector4<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
325      #[cfg(feature = "row_vectord")]
326      $op!([<$lib RDRD>], RowDVector<$in>, RowDVector<$in>, RowDVector<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
327      // Vector Vector
328      #[cfg(feature = "vector2")]
329      $op!([<$lib V2V2>], Vector2<$in>, Vector2<$in>, Vector2<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
330      #[cfg(feature = "vector3")]
331      $op!([<$lib V3V3>], Vector3<$in>, Vector3<$in>, Vector3<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
332      #[cfg(feature = "vector4")]
333      $op!([<$lib V4V4>], Vector4<$in>, Vector4<$in>, Vector4<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
334      #[cfg(feature = "vectord")]
335      $op!([<$lib VDVD>], DVector<$in>, DVector<$in>, DVector<$out>, [<$lib:lower _vec_op>], FeatureFlag::Builtin(FeatureKind::$lib));
336    }
337  }}
338
339#[macro_export]
340macro_rules! impl_binop_match_arms {
341  ($lib:ident, $arg:expr, $($lhs_type:ident, $($target_type:ident, $value_string:tt),+);+ $(;)?) => {
342    paste!{
343      match $arg {
344        $(
345          $(
346            // Scalar Scalar
347            #[cfg(all(feature = $value_string))]
348            (Value::$lhs_type(lhs), Value::$lhs_type(rhs)) => Ok(Box::new([<$lib SS>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new($target_type::default()) })),
349            // Scalar Matrix
350            #[cfg(all(feature = $value_string, feature = "matrix1"))]
351            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Matrix1(rhs))) => Ok(Box::new([<$lib SM1>]{lhs, rhs, out: Ref::new(Matrix1::from_element($target_type::default()))})),
352            #[cfg(all(feature = $value_string, feature = "matrix2"))]
353            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib SM2>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),
354            #[cfg(all(feature = $value_string, feature = "matrix3"))]
355            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib SM3>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),
356            #[cfg(all(feature = $value_string, feature = "matrix4"))]
357            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib SM4>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),
358            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
359            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib SM2x3>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),
360            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
361            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib SM3x2>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),
362            #[cfg(all(feature = $value_string, feature = "matrixd"))]
363            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::DMatrix(rhs))) => {
364              let (rows,cols) = {rhs.borrow().shape()};
365              Ok(Box::new([<$lib SMD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))}))
366            },   
367            // Scalar Row
368            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
369            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib SR2>]{lhs, rhs, out: Ref::new(RowVector2::from_element($target_type::default()))})),
370            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
371            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib SR3>]{lhs, rhs, out: Ref::new(RowVector3::from_element($target_type::default()))})),
372            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
373            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib SR4>]{lhs, rhs, out: Ref::new(RowVector4::from_element($target_type::default()))})),
374            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
375            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::RowDVector(rhs))) => Ok(Box::new([<$lib SRD>]{lhs, rhs: rhs.clone(), out: Ref::new(RowDVector::from_element(rhs.borrow().len(),$target_type::default()))})),
376            // Scalar Vector
377            #[cfg(all(feature = $value_string, feature = "vector2"))]
378            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Vector2(rhs))) => Ok(Box::new([<$lib SV2>]{lhs, rhs, out: Ref::new(Vector2::from_element($target_type::default()))})),
379            #[cfg(all(feature = $value_string, feature = "vector3"))]
380            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Vector3(rhs))) => Ok(Box::new([<$lib SV3>]{lhs, rhs, out: Ref::new(Vector3::from_element($target_type::default()))})),
381            #[cfg(all(feature = $value_string, feature = "vector4"))]
382            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::Vector4(rhs))) => Ok(Box::new([<$lib SV4>]{lhs, rhs, out: Ref::new(Vector4::from_element($target_type::default()))})),
383            #[cfg(all(feature = $value_string, feature = "vectord"))]
384            (Value::$lhs_type(lhs), Value::[<Matrix $lhs_type>](Matrix::DVector(rhs))) => Ok(Box::new([<$lib SVD>]{lhs, rhs: rhs.clone(), out: Ref::new(DVector::from_element(rhs.borrow().len(),$target_type::default()))})),
385            // Matrix Scalar
386            #[cfg(all(feature = $value_string, feature = "matrix1"))]
387            (Value::[<Matrix $lhs_type>](Matrix::Matrix1(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M1S>]{lhs, rhs, out: Ref::new(Matrix1::from_element($target_type::default()))})),
388            #[cfg(all(feature = $value_string, feature = "matrix2"))]
389            (Value::[<Matrix $lhs_type>](Matrix::Matrix2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2S>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),
390            #[cfg(all(feature = $value_string, feature = "matrix3"))]
391            (Value::[<Matrix $lhs_type>](Matrix::Matrix3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3S>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),
392            #[cfg(all(feature = $value_string, feature = "matrix4"))]
393            (Value::[<Matrix $lhs_type>](Matrix::Matrix4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M4S>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),
394            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
395            (Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M2x3S>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),
396            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
397            (Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib M3x2S>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),
398            #[cfg(all(feature = $value_string, feature = "matrixd"))]
399            (Value::[<Matrix $lhs_type>](Matrix::DMatrix(lhs)),Value::$lhs_type(rhs)) => {
400              let (rows,cols) = {lhs.borrow().shape()};
401              Ok(Box::new([<$lib MDS>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))}))
402            },
403            // Row Scalar
404            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
405            (Value::[<Matrix $lhs_type>](Matrix::RowVector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R2S>]{lhs, rhs, out: Ref::new(RowVector2::from_element($target_type::default()))})),
406            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
407            (Value::[<Matrix $lhs_type>](Matrix::RowVector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R3S>]{lhs, rhs, out: Ref::new(RowVector3::from_element($target_type::default()))})),
408            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
409            (Value::[<Matrix $lhs_type>](Matrix::RowVector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib R4S>]{lhs, rhs, out: Ref::new(RowVector4::from_element($target_type::default()))})),
410            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
411            (Value::[<Matrix $lhs_type>](Matrix::RowDVector(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib RDS>]{lhs: lhs.clone(), rhs, out: Ref::new(RowDVector::from_element(lhs.borrow().len(),$target_type::default()))})),
412            // Vector Scalar
413            #[cfg(all(feature = $value_string, feature = "vector2"))]
414            (Value::[<Matrix $lhs_type>](Matrix::Vector2(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V2S>]{lhs, rhs, out: Ref::new(Vector2::from_element($target_type::default()))})),
415            #[cfg(all(feature = $value_string, feature = "vector3"))]
416            (Value::[<Matrix $lhs_type>](Matrix::Vector3(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V3S>]{lhs, rhs, out: Ref::new(Vector3::from_element($target_type::default()))})),
417            #[cfg(all(feature = $value_string, feature = "vector4"))]
418            (Value::[<Matrix $lhs_type>](Matrix::Vector4(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib V4S>]{lhs, rhs, out: Ref::new(Vector4::from_element($target_type::default()))})),
419            #[cfg(all(feature = $value_string, feature = "vectord"))]
420            (Value::[<Matrix $lhs_type>](Matrix::DVector(lhs)),Value::$lhs_type(rhs)) => Ok(Box::new([<$lib VDS>]{lhs: lhs.clone(), rhs, out: Ref::new(DVector::from_element(lhs.borrow().len(),$target_type::default()))})),
421            // Matrix Matrix
422            #[cfg(all(feature = $value_string, feature = "matrix1"))]
423            (Value::[<Matrix $lhs_type>](Matrix::Matrix1(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix1(rhs))) => Ok(Box::new([<$lib M1M1>]{lhs, rhs, out: Ref::new(Matrix1::from_element($target_type::default()))})),
424            #[cfg(all(feature = $value_string, feature = "matrix2"))]
425            (Value::[<Matrix $lhs_type>](Matrix::Matrix2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib M2M2>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),
426            #[cfg(all(feature = $value_string, feature = "matrix3"))]
427            (Value::[<Matrix $lhs_type>](Matrix::Matrix3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib M3M3>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),
428            #[cfg(all(feature = $value_string, feature = "matrix4"))]
429            (Value::[<Matrix $lhs_type>](Matrix::Matrix4(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib M4M4>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),
430            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
431            (Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib M2x3M2x3>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),  
432            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
433            (Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib M3x2M3x2>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),
434            #[cfg(all(feature = $value_string, feature = "matrixd"))]
435            (Value::[<Matrix $lhs_type>](Matrix::DMatrix(lhs)), Value::[<Matrix $lhs_type>](Matrix::DMatrix(rhs))) => {
436              let (rows,cols) = {lhs.borrow().shape()};
437              Ok(Box::new([<$lib MDMD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))}))
438            },
439            // Row Row
440            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
441            (Value::[<Matrix $lhs_type>](Matrix::RowVector2(lhs)), Value::[<Matrix $lhs_type>](Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib R2R2>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(RowVector2::from_element($target_type::default())) })),
442            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
443            (Value::[<Matrix $lhs_type>](Matrix::RowVector3(lhs)), Value::[<Matrix $lhs_type>](Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib R3R3>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(RowVector3::from_element($target_type::default())) })),
444            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
445            (Value::[<Matrix $lhs_type>](Matrix::RowVector4(lhs)), Value::[<Matrix $lhs_type>](Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib R4R4>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(RowVector4::from_element($target_type::default())) })),
446            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
447            (Value::[<Matrix $lhs_type>](Matrix::RowDVector(lhs)), Value::[<Matrix $lhs_type>](Matrix::RowDVector(rhs))) => Ok(Box::new([<$lib RDRD>]{lhs: lhs.clone(), rhs, out: Ref::new(RowDVector::from_element(lhs.borrow().len(),$target_type::default()))})),
448            // Vector Vector
449            #[cfg(all(feature = $value_string, feature = "vector2"))]
450            (Value::[<Matrix $lhs_type>](Matrix::Vector2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Vector2(rhs))) => Ok(Box::new([<$lib V2V2>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(Vector2::from_element($target_type::default())) })),
451            #[cfg(all(feature = $value_string, feature = "vector3"))]
452            (Value::[<Matrix $lhs_type>](Matrix::Vector3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Vector3(rhs))) => Ok(Box::new([<$lib V3V3>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(Vector3::from_element($target_type::default())) })),
453            #[cfg(all(feature = $value_string, feature = "vector4"))]
454            (Value::[<Matrix $lhs_type>](Matrix::Vector4(lhs)), Value::[<Matrix $lhs_type>](Matrix::Vector4(rhs))) => Ok(Box::new([<$lib V4V4>]{lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(Vector4::from_element($target_type::default())) })),
455            #[cfg(all(feature = $value_string, feature = "vectord"))]
456            (Value::[<Matrix $lhs_type>](Matrix::DVector(lhs)), Value::[<Matrix $lhs_type>](Matrix::DVector(rhs))) => Ok(Box::new([<$lib VDVD>]{lhs: lhs.clone(), rhs, out: Ref::new(DVector::from_element(lhs.borrow().len(),$target_type::default()))})),
457            // Matrix Vector     
458            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "vector2"))]
459            (Value::[<Matrix $lhs_type>](Matrix::Matrix2(lhs)),Value::[<Matrix $lhs_type>](Matrix::Vector2(rhs))) => Ok(Box::new([<$lib M2V2>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),         
460            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "vector3"))]
461            (Value::[<Matrix $lhs_type>](Matrix::Matrix3(lhs)),Value::[<Matrix $lhs_type>](Matrix::Vector3(rhs))) => Ok(Box::new([<$lib M3V3>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),         
462            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "vector2"))]
463            (Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(lhs)),Value::[<Matrix $lhs_type>](Matrix::Vector2(rhs))) => Ok(Box::new([<$lib M2x3V2>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),         
464            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "vector3"))]
465            (Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(lhs)),Value::[<Matrix $lhs_type>](Matrix::Vector3(rhs))) => Ok(Box::new([<$lib M3x2V3>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),         
466            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "vector4"))]
467            (Value::[<Matrix $lhs_type>](Matrix::Matrix4(lhs)),Value::[<Matrix $lhs_type>](Matrix::Vector4(rhs))) => Ok(Box::new([<$lib M4V4>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),         
468            // Vector Matrix
469            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "row_vector2"))]
470            (Value::[<Matrix $lhs_type>](Matrix::Matrix2(lhs)),Value::[<Matrix $lhs_type>](Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib M2R2>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),         
471            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "row_vector3"))]
472            (Value::[<Matrix $lhs_type>](Matrix::Matrix3(lhs)),Value::[<Matrix $lhs_type>](Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib M3R3>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),         
473            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "row_vector3"))]
474            (Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(lhs)),Value::[<Matrix $lhs_type>](Matrix::RowVector3(rhs))) => Ok(Box::new([<$lib M2x3R3>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),         
475            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "row_vector2"))]
476            (Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(lhs)),Value::[<Matrix $lhs_type>](Matrix::RowVector2(rhs))) => Ok(Box::new([<$lib M3x2R2>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),         
477            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "row_vector4"))]
478            (Value::[<Matrix $lhs_type>](Matrix::Matrix4(lhs)),Value::[<Matrix $lhs_type>](Matrix::RowVector4(rhs))) => Ok(Box::new([<$lib M4R4>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),         
479            #[cfg(all(feature = $value_string, feature = "matrixd"))]
480            (Value::[<Matrix $lhs_type>](Matrix::DMatrix(lhs)),Value::[<Matrix $lhs_type>](rhs)) => {
481              let (rows,cols) = {lhs.borrow().shape()};
482              let rhs_shape = rhs.shape();
483              match (rows,cols,rhs_shape[0],rhs_shape[1]) {
484                // matching rows
485                (n,_,m,1) if n == m => (),
486                // matching cols
487                (_,n,1,m) if n == m => (),
488                // mismatching dimensions
489                _ => {return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
490              }
491              match rhs {
492                #[cfg(feature = "vector2")]
493                Matrix::Vector2(rhs) => Ok(Box::new([<$lib MDV2>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
494                #[cfg(feature = "vector3")]
495                Matrix::Vector3(rhs) => Ok(Box::new([<$lib MDV3>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
496                #[cfg(feature = "vector4")]
497                Matrix::Vector4(rhs) => Ok(Box::new([<$lib MDV4>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
498                #[cfg(feature = "vectord")]
499                Matrix::DVector(rhs) => Ok(Box::new([<$lib MDVD>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
500                #[cfg(feature = "row_vector2")]
501                Matrix::RowVector2(rhs) => Ok(Box::new([<$lib MDR2>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
502                #[cfg(reature = "row_vector3")]
503                Matrix::RowVector3(rhs) => Ok(Box::new([<$lib MDR3>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
504                #[cfg(feature = "row_vector4")]
505                Matrix::RowVector4(rhs) => Ok(Box::new([<$lib MDR4>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
506                #[cfg(feature = "row_vectord")]
507                Matrix::RowDVector(rhs) => Ok(Box::new([<$lib MDRD>]{lhs: lhs.clone(), rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
508                _ => {return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
509              }
510            },
511            // Vector Matrix
512            #[cfg(all(feature = $value_string, feature = "matrix2", feature = "vector2"))]
513            (Value::[<Matrix $lhs_type>](Matrix::Vector2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib V2M2>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),         
514            #[cfg(all(feature = $value_string, feature = "matrix3", feature = "vector3"))]
515            (Value::[<Matrix $lhs_type>](Matrix::Vector3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib V3M3>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),         
516            #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "vector2"))]
517            (Value::[<Matrix $lhs_type>](Matrix::Vector2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib V2M2x3>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),         
518            #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "vector3"))]
519            (Value::[<Matrix $lhs_type>](Matrix::Vector3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib V3M3x2>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),                     
520            #[cfg(all(feature = $value_string, feature = "matrix4", feature = "vector4"))]
521            (Value::[<Matrix $lhs_type>](Matrix::Vector4(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib V4M4>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),                     
522            // Row Matrix     
523            #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "matrix2"))]
524            (Value::[<Matrix $lhs_type>](Matrix::RowVector2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix2(rhs))) => Ok(Box::new([<$lib R2M2>]{lhs, rhs, out: Ref::new(Matrix2::from_element($target_type::default()))})),         
525            #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "matrix3"))]
526            (Value::[<Matrix $lhs_type>](Matrix::RowVector3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix3(rhs))) => Ok(Box::new([<$lib R3M3>]{lhs, rhs, out: Ref::new(Matrix3::from_element($target_type::default()))})),         
527            #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "matrix2x3"))]
528            (Value::[<Matrix $lhs_type>](Matrix::RowVector3(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(rhs))) => Ok(Box::new([<$lib R3M2x3>]{lhs, rhs, out: Ref::new(Matrix2x3::from_element($target_type::default()))})),         
529            #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "matrix3x2"))]
530            (Value::[<Matrix $lhs_type>](Matrix::RowVector2(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(rhs))) => Ok(Box::new([<$lib R2M3x2>]{lhs, rhs, out: Ref::new(Matrix3x2::from_element($target_type::default()))})),         
531            #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "matrix4"))]
532            (Value::[<Matrix $lhs_type>](Matrix::RowVector4(lhs)), Value::[<Matrix $lhs_type>](Matrix::Matrix4(rhs))) => Ok(Box::new([<$lib R4M4>]{lhs, rhs, out: Ref::new(Matrix4::from_element($target_type::default()))})),         
533            #[cfg(all(feature = $value_string, feature = "matrixd"))]
534            (Value::[<Matrix $lhs_type>](lhs),Value::[<Matrix $lhs_type>](Matrix::DMatrix(rhs))) => {
535              let (rows,cols) = {rhs.borrow().shape()};
536              let lhs_shape = lhs.shape();
537              match (lhs_shape[0],lhs_shape[1],rows,cols) {
538                // matching rows
539                (m,1,n,_) if n == m => (),
540                // matching cols
541                (1,m,_,n) if n == m => (),
542                // mismatching dimensions
543                _ => {return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
544              }
545              match lhs {
546                #[cfg(feature = "vector2")]
547                Matrix::Vector2(lhs) => Ok(Box::new([<$lib V2MD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
548                #[cfg(feature = "vector3")]
549                Matrix::Vector3(lhs) => Ok(Box::new([<$lib V3MD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
550                #[cfg(feature = "vector4")]
551                Matrix::Vector4(lhs) => Ok(Box::new([<$lib V4MD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
552                #[cfg(feature = "vectord")]
553                Matrix::DVector(lhs) => Ok(Box::new([<$lib VDMD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
554                #[cfg(feature = "row_vector2")]
555                Matrix::RowVector2(lhs) => Ok(Box::new([<$lib R2MD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
556                #[cfg(feature = "row_vector3")]
557                Matrix::RowVector3(lhs) => Ok(Box::new([<$lib R3MD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
558                #[cfg(feature = "row_vector4")]
559                Matrix::RowVector4(lhs) => Ok(Box::new([<$lib R4MD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
560                #[cfg(feature = "row_vectord")]
561                Matrix::RowDVector(lhs) => Ok(Box::new([<$lib RDMD>]{lhs, rhs, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default()))})),
562                _ => {return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });},
563              }
564            }
565          )+
566        )+
567        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
568      }
569    }
570  }
571}  
572
573#[macro_export]
574macro_rules! impl_urnop_match_arms {
575  ($lib:tt, $arg:tt, $($lhs_type:tt, $($target_type:tt, $value_string:tt),+);+ $(;)?) => {
576    paste!{
577      match $arg {
578        $(
579          $(
580            #[cfg(feature = $value_string)]
581            (Value::$lhs_type(arg)) => Ok(Box::new([<$lib S>]{arg: arg.clone(), out: Ref::new($target_type::default()), _marker: PhantomData::default() })),
582            #[cfg(all(feature = $value_string, feature = "matrix1"))]
583            (Value::[<Matrix $lhs_type>](Matrix::Matrix1(arg))) => Ok(Box::new([<$lib V>]{arg, out: Ref::new(Matrix1::from_element($target_type::default())), _marker: PhantomData::default() })),
584            #[cfg(all(feature = $value_string, feature = "matrix2"))]
585            (Value::[<Matrix $lhs_type>](Matrix::Matrix2(arg))) => Ok(Box::new([<$lib V>]{arg, out: Ref::new(Matrix2::from_element($target_type::default())), _marker: PhantomData::default() })),
586            #[cfg(all(feature = $value_string, feature = "matrix3"))]
587            (Value::[<Matrix $lhs_type>](Matrix::Matrix3(arg))) => Ok(Box::new([<$lib V>]{arg, out: Ref::new(Matrix3::from_element($target_type::default())), _marker: PhantomData::default() })),
588            #[cfg(all(feature = $value_string, feature = "matrix4"))]
589            (Value::[<Matrix $lhs_type>](Matrix::Matrix4(arg))) => Ok(Box::new([<$lib V>]{arg, out: Ref::new(Matrix4::from_element($target_type::default())), _marker: PhantomData::default() })),
590            #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
591            (Value::[<Matrix $lhs_type>](Matrix::Matrix2x3(arg))) => Ok(Box::new([<$lib V>]{arg, out: Ref::new(Matrix2x3::from_element($target_type::default())), _marker: PhantomData::default() })),         
592            #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
593            (Value::[<Matrix $lhs_type>](Matrix::Matrix3x2(arg))) => Ok(Box::new([<$lib V>]{arg, out: Ref::new(Matrix3x2::from_element($target_type::default())), _marker: PhantomData::default() })),         
594            #[cfg(all(feature = $value_string, feature = "row_vector2"))]
595            (Value::[<Matrix $lhs_type>](Matrix::RowVector2(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(RowVector2::from_element($target_type::default())), _marker: PhantomData::default() })),
596            #[cfg(all(feature = $value_string, feature = "row_vector3"))]
597            (Value::[<Matrix $lhs_type>](Matrix::RowVector3(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(RowVector3::from_element($target_type::default())), _marker: PhantomData::default() })),
598            #[cfg(all(feature = $value_string, feature = "row_vector4"))]
599            (Value::[<Matrix $lhs_type>](Matrix::RowVector4(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(RowVector4::from_element($target_type::default())), _marker: PhantomData::default() })),
600            #[cfg(all(feature = $value_string, feature = "row_vectord"))]
601            (Value::[<Matrix $lhs_type>](Matrix::RowDVector(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(RowDVector::from_element(arg.borrow().len(),$target_type::default())), _marker: PhantomData::default() })),
602            #[cfg(all(feature = $value_string, feature = "vector2"))]
603            (Value::[<Matrix $lhs_type>](Matrix::Vector2(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(Vector2::from_element($target_type::default())), _marker: PhantomData::default() })),
604            #[cfg(all(feature = $value_string, feature = "vector3"))]
605            (Value::[<Matrix $lhs_type>](Matrix::Vector3(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(Vector3::from_element($target_type::default())), _marker: PhantomData::default() })),
606            #[cfg(all(feature = $value_string, feature = "vector4"))]
607            (Value::[<Matrix $lhs_type>](Matrix::Vector4(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(Vector4::from_element($target_type::default())), _marker: PhantomData::default() })),
608            #[cfg(all(feature = $value_string, feature = "vectord"))]
609            (Value::[<Matrix $lhs_type>](Matrix::DVector(arg))) => Ok(Box::new([<$lib V>]{arg: arg.clone(), out: Ref::new(DVector::from_element(arg.borrow().len(),$target_type::default())), _marker: PhantomData::default() })),
610            #[cfg(all(feature = $value_string, feature = "matrixd"))]
611            (Value::[<Matrix $lhs_type>](Matrix::DMatrix(arg))) => {
612              let (rows,cols) = {arg.borrow().shape()};
613              Ok(Box::new([<$lib V>]{arg, out: Ref::new(DMatrix::from_element(rows,cols,$target_type::default())), _marker: PhantomData::default() }))},
614          )+
615        )+
616        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
617      }
618    }
619  }
620}
621
622#[macro_export]
623macro_rules! impl_mech_binop_fxn {
624  ($fxn_name:ident, $gen_fxn:tt) => {
625    pub struct $fxn_name {}
626    impl NativeFunctionCompiler for $fxn_name {
627      fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
628        if arguments.len() != 2 {
629          return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
630        }
631        let lhs_value = arguments[0].clone();
632        let rhs_value = arguments[1].clone();
633        match $gen_fxn(lhs_value.clone(), rhs_value.clone()) {
634          Ok(fxn) => Ok(fxn),
635          Err(_) => {
636            match (lhs_value,rhs_value) {
637              (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {$gen_fxn(lhs.borrow().clone(), rhs.borrow().clone())}
638              (lhs_value,Value::MutableReference(rhs)) => { $gen_fxn(lhs_value.clone(), rhs.borrow().clone())}
639              (Value::MutableReference(lhs),rhs_value) => { $gen_fxn(lhs.borrow().clone(), rhs_value.clone()) }
640              x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
641            }
642          }
643        }
644      }
645    }
646  }
647}
648
649#[macro_export]
650macro_rules! impl_mech_urnop_fxn {
651  ($fxn_name:ident, $gen_fxn:tt) => {
652    pub struct $fxn_name {}
653    impl NativeFunctionCompiler for $fxn_name {
654      fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
655        if arguments.len() != 1 {
656          return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
657        }
658        let input = arguments[0].clone();
659        match $gen_fxn(input.clone()) {
660          Ok(fxn) => Ok(fxn),
661          Err(_) => {
662            match (input) {
663              (Value::MutableReference(input)) => {$gen_fxn(input.borrow().clone())}
664              x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:#?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
665            }
666          }
667        }
668      }
669    }
670  }
671}
672
673#[macro_export]
674macro_rules! impl_set_range_all_match_arms {
675  ($fxn_name:ident, $arg:expr, $($value_kind:ident, $value_string:tt);+ $(;)?) => {
676    paste!{
677      match $arg {
678        $(
679          // Vector Scalar
680          #[cfg(all(feature = $value_string, feature = "matrix4"))]
681          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
682          #[cfg(all(feature = $value_string, feature = "matrix3"))]
683          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
684          #[cfg(all(feature = $value_string, feature = "matrix2"))]
685          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
686          #[cfg(all(feature = $value_string, feature = "matrix1"))]
687          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
688          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
689          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
690          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
691          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
692          #[cfg(all(feature = $value_string, feature = "matrixd"))]
693          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
694          
695          // Vector Vector
696          #[cfg(all(feature = $value_string, feature = "matrixd"))]
697          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
698          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "matrix2"))]
699          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
700          
701          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "matrix2x3"))]
702          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2x3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
703          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "matrix3"))]
704          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
705          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "matrix3x2"))]
706          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3x2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
707          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "matrix4"))]
708          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix4(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
709          
710          #[cfg(all(feature = $value_string, feature = "matrix2"))]
711          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
712          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "matrix3x2"))]
713          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3x2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
714          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "matrixd"))]
715          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
716
717          #[cfg(all(feature = $value_string, feature = "matrix3"))]
718          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
719          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "matrix2x3"))]
720          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2x3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
721          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "matrixd"))]
722          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
723
724          #[cfg(all(feature = $value_string, feature = "matrix4"))]
725          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix4(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
726          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "matrixd"))]
727          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
728
729          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
730          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2x3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
731          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "matrix3"))]
732          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
733          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "matrixd"))]
734          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
735
736          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
737          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3x2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
738          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "matrix2"))]
739          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
740          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "matrixd"))]
741          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name V>]{ sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
742
743          // Matrix Scalar Bool
744          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
745          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
746          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
747          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
748          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
749          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
750          #[cfg(all(feature = $value_string, feature = "matrix1", feature = "bool"))]
751          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
752          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
753          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
754          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
755          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
756          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
757          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name SB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
758        
759          // Matrix Vector Bool
760          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
761          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name VB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
762          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
763          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name VB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
764          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
765          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name VB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
766          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
767          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix4(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name VB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
768          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
769          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix2x3(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name VB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
770          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
771          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixBool(Matrix::DVector(ix)),Value::IndexAll], Value::[<Matrix $value_kind>](Matrix::Matrix3x2(source))) if ix.borrow().len() == source.borrow().nrows() && sink.borrow().ncols() == source.borrow().ncols() => Ok(Box::new([<$fxn_name VB>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
772        )+
773        x => {
774          println!("{:#?}", x);
775          Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind })
776        }
777      }
778    }
779  }
780}
781
782#[macro_export]
783macro_rules! impl_set_range_match_arms {
784  ($fxn_name:ident, $arg:expr, $($value_kind:ident,$value_string:tt);+ $(;)?) => {
785    paste!{
786      match $arg {
787        $(
788          // Set vector
789          #[cfg(all(feature = $value_string, feature = "row_vector4"))]
790          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::RowVector4(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
791          #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "row_vector3"))]
792          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::RowVector3(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
793          #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "row_vector2"))]
794          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::RowVector2(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
795          #[cfg(all(feature = $value_string, feature = "vector4"))]
796          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::Vector4(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
797          #[cfg(all(feature = $value_string, feature = "vector4", feature = "vector3"))]
798          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::Vector3(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
799          #[cfg(all(feature = $value_string, feature = "vector4", feature = "vector2"))]
800          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::Vector2(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
801
802          // Set Matrix
803          #[cfg(all(feature = $value_string, feature = "matrixd"))]
804          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) => Ok(Box::new([<$fxn_name V>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
805          
806          // Set scalar
807          #[cfg(all(feature = $value_string, feature = "row_vector4"))]
808          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),            
809          #[cfg(all(feature = $value_string, feature = "row_vector3"))]
810          (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
811          #[cfg(all(feature = $value_string, feature = "row_vector2"))]
812          (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
813          #[cfg(all(feature = $value_string, feature = "vector4"))]
814          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
815          #[cfg(all(feature = $value_string, feature = "vector3"))]
816          (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
817          #[cfg(all(feature = $value_string, feature = "vector2"))]
818          (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
819          #[cfg(all(feature = $value_string, feature = "matrix4"))]
820          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
821          #[cfg(all(feature = $value_string, feature = "matrix3"))]
822          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
823          #[cfg(all(feature = $value_string, feature = "matrix2"))]
824          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
825          #[cfg(all(feature = $value_string, feature = "matrix1"))]
826          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
827          #[cfg(all(feature = $value_string, feature = "matrix2x3"))]
828          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
829          #[cfg(all(feature = $value_string, feature = "matrix3x2"))]
830          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
831          #[cfg(all(feature = $value_string, feature = "matrixd"))]
832          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
833          #[cfg(all(feature = $value_string, feature = "row_vectord"))]
834          (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)),[Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
835          #[cfg(all(feature = $value_string, feature = "vectord"))]
836          (Value::[<Matrix $value_kind>](Matrix::DVector(sink)),   [Value::MatrixIndex(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name S>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
837
838          // Bool
839          #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "bool"))]
840          (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
841          #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "bool"))]
842          (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
843          #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "bool"))]
844          (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
845          #[cfg(all(feature = $value_string, feature = "vector4", feature = "bool"))]
846          (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
847          #[cfg(all(feature = $value_string, feature = "vector3", feature = "bool"))]
848          (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
849          #[cfg(all(feature = $value_string, feature = "vector2", feature = "bool"))]
850          (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
851          #[cfg(all(feature = $value_string, feature = "matrix4", feature = "bool"))]
852          (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
853          #[cfg(all(feature = $value_string, feature = "matrix3", feature = "bool"))]
854          (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
855          #[cfg(all(feature = $value_string, feature = "matrix2", feature = "bool"))]
856          (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
857          #[cfg(all(feature = $value_string, feature = "matrix1", feature = "bool"))]
858          (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
859          #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "bool"))]
860          (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
861          #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "bool"))]
862          (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),            
863          #[cfg(all(feature = $value_string, feature = "matrixd", feature = "bool"))]
864          (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
865          #[cfg(all(feature = $value_string, feature = "vectord", feature = "bool"))]
866          (Value::[<Matrix $value_kind>](Matrix::DVector(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
867          #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "bool"))]
868          (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)),[Value::MatrixBool(Matrix::DVector(ix))], Value::$value_kind(source)) => Ok(Box::new([<$fxn_name B>] { sink: sink.clone(), ixes: ix.clone(), source: source.clone(), _marker: PhantomData::default() })),
869        )+
870        x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
871      }
872    }
873  }
874}