1#[macro_use]
2use crate::stdlib::*;
3
4macro_rules! register_vertical_concatenate_fxn {
5 ($name:ident) => {
6 register_fxn_descriptor!(
7 $name,
8 bool, "bool",
9 String, "string",
10 u8, "u8",
11 u16, "u16",
12 u32, "u32",
13 u64, "u64",
14 u128, "u128",
15 i8, "i8",
16 i16, "i16",
17 i32, "i32",
18 i64, "i64",
19 i128, "i128",
20 f32, "f32",
21 f64, "f64",
22 C64, "c64",
23 R64, "r64"
24 );
25 };
26}
27
28macro_rules! register_fxns {
29 ($op:ident) => {
30 $op!(bool, "bool");
31 $op!(String, "string");
32 $op!(u8, "u8");
33 $op!(u16, "u16");
34 $op!(u32, "u32");
35 $op!(u64, "u64");
36 $op!(u128, "u128");
37 $op!(i8, "i8");
38 $op!(i16, "i16");
39 $op!(i32, "i32");
40 $op!(i64, "i64");
41 $op!(i128, "i128");
42 $op!(f64, "f64");
43 $op!(f32, "f32");
44 $op!(R64, "r64");
45 $op!(C64, "c64");
46 }
47}
48
49
50macro_rules! vertcat_two_args {
53 ($fxn:ident, $e0:ident, $e1:ident, $out:ident, $opt:ident) => {
54 #[derive(Debug)]
55 struct $fxn<T> {
56 e0: Ref<$e0<T>>,
57 e1: Ref<$e1<T>>,
58 out: Ref<$out<T>>,
59 }
60 impl<T> MechFunctionFactory for $fxn<T>
61 where
62 T: Debug + Clone + Sync + Send + PartialEq + 'static +
63 ConstElem + CompileConst + AsValueKind,
64 Ref<$out<T>>: ToValue
65 {
66 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
67 match args {
68 FunctionArgs::Binary(out, arg0, arg1) => {
69 let e0: Ref<$e0<T>> = unsafe { arg0.as_unchecked() }.clone();
70 let e1: Ref<$e1<T>> = unsafe { arg1.as_unchecked() }.clone();
71 let out: Ref<$out<T>> = unsafe { out.as_unchecked() }.clone();
72 Ok(Box::new(Self { e0, e1, out }))
73 },
74 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 2, found: args.len()}, None).with_compiler_loc())
75 }
76 }
77 }
78 impl<T> MechFunctionImpl for $fxn<T>
79 where
80 T: Debug + Clone + Sync + Send + PartialEq + 'static,
81 Ref<$out<T>>: ToValue
82 {
83 fn solve(&self) {
84 unsafe {
85 let e0_ptr = (*(self.e0.as_ptr())).clone();
86 let e1_ptr = (*(self.e1.as_ptr())).clone();
87 let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
88 $opt!(out_ptr, e0_ptr, e1_ptr);
89 }
90 }
91 fn out(&self) -> Value { self.out.to_value() }
92 fn to_string(&self) -> String { format!("{:#?}", self) }
93 }
94 #[cfg(feature = "compiler")]
95 impl<T> MechFunctionCompiler for $fxn<T>
96 where
97 T: ConstElem + CompileConst + AsValueKind
98 {
99 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
100 let name = format!("{}<{}{}{}{}>", stringify!($fxn), T::as_value_kind(), stringify!($out), stringify!($e0), stringify!($e1));
101 compile_binop!(name, self.out, self.e0, self.e1, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
102 }
103 }
104 macro_rules! register_vertcat_fxn {
105 ($type:ty, $type_string:tt) => {
106 paste!{
107 #[cfg(feature = $type_string)]
108 register_descriptor! {
109 FunctionDescriptor {
110 name: concat!(stringify!($fxn), "<", stringify!([<$type:lower>]), stringify!($out), stringify!($e0), stringify!($e1), ">"),
111 ptr: $fxn::<$type>::new,
112 }
113 }
114 }
115 };
116 }
117 register_fxns!(register_vertcat_fxn);
118 };
119}
120
121macro_rules! vertcat_three_args {
122 ($fxn:ident, $e0:ident, $e1:ident, $e2:ident, $out:ident, $opt:ident) => {
123 #[derive(Debug)]
124 struct $fxn<T> {
125 e0: Ref<$e0<T>>,
126 e1: Ref<$e1<T>>,
127 e2: Ref<$e2<T>>,
128 out: Ref<$out<T>>,
129 }
130 impl<T> MechFunctionFactory for $fxn<T>
131 where
132 T: Debug + Clone + Sync + Send + PartialEq + 'static +
133 ConstElem + CompileConst + AsValueKind,
134 Ref<$out<T>>: ToValue
135 {
136 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
137 match args {
138 FunctionArgs::Ternary(out, arg0, arg1, arg2) => {
139 let e0: Ref<$e0<T>> = unsafe { arg0.as_unchecked() }.clone();
140 let e1: Ref<$e1<T>> = unsafe { arg1.as_unchecked() }.clone();
141 let e2: Ref<$e2<T>> = unsafe { arg2.as_unchecked() }.clone();
142 let out: Ref<$out<T>> = unsafe { out.as_unchecked() }.clone();
143 Ok(Box::new(Self { e0, e1, e2, out }))
144 },
145 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 3, found: args.len()}, None).with_compiler_loc())
146 }
147 }
148 }
149 impl<T> MechFunctionImpl for $fxn<T>
150 where
151 T: Debug + Clone + Sync + Send + PartialEq + 'static,
152 Ref<$out<T>>: ToValue
153 {
154 fn solve(&self) {
155 unsafe {
156 let e0_ptr = (*(self.e0.as_ptr())).clone();
157 let e1_ptr = (*(self.e1.as_ptr())).clone();
158 let e2_ptr = (*(self.e2.as_ptr())).clone();
159 let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
160 $opt!(out_ptr,e0_ptr,e1_ptr,e2_ptr);
161 }
162 }
163 fn out(&self) -> Value { self.out.to_value() }
164 fn to_string(&self) -> String { format!("{:#?}", self) }
165 }
166 #[cfg(feature = "compiler")]
167 impl<T> MechFunctionCompiler for $fxn<T>
168 where
169 T: ConstElem + CompileConst + AsValueKind + AsValueKind
170 {
171 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
172 let name = format!("{}<{}>", stringify!($fxn), T::as_value_kind());
173 compile_ternop!(name, self.out, self.e0, self.e1, self.e2, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
174 }
175 }
176 register_vertical_concatenate_fxn!($fxn);
177 };}
178
179macro_rules! vertcat_four_args {
180 ($fxn:ident, $e0:ident, $e1:ident, $e2:ident, $e3:ident, $out:ident, $opt:ident) => {
181 #[derive(Debug)]
182 struct $fxn<T> {
183 e0: Ref<$e0<T>>,
184 e1: Ref<$e1<T>>,
185 e2: Ref<$e2<T>>,
186 e3: Ref<$e3<T>>,
187 out: Ref<$out<T>>,
188 }
189 impl<T> MechFunctionFactory for $fxn<T>
190 where
191 T: Debug + Clone + Sync + Send + PartialEq + 'static +
192 ConstElem + CompileConst + AsValueKind,
193 Ref<$out<T>>: ToValue
194 {
195 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
196 match args {
197 FunctionArgs::Quaternary(out, arg0, arg1, arg2, arg3) => {
198 let e0: Ref<$e0<T>> = unsafe { arg0.as_unchecked() }.clone();
199 let e1: Ref<$e1<T>> = unsafe { arg1.as_unchecked() }.clone();
200 let e2: Ref<$e2<T>> = unsafe { arg2.as_unchecked() }.clone();
201 let e3: Ref<$e3<T>> = unsafe { arg3.as_unchecked() }.clone();
202 let out: Ref<$out<T>> = unsafe { out.as_unchecked() }.clone();
203 Ok(Box::new(Self { e0, e1, e2, e3, out }))
204 },
205 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 4, found: args.len()}, None).with_compiler_loc())
206 }
207 }
208 }
209 impl<T> MechFunctionImpl for $fxn<T>
210 where
211 T: Debug + Clone + Sync + Send + PartialEq + 'static,
212 Ref<$out<T>>: ToValue
213 {
214 fn solve(&self) {
215 unsafe {
216 let e0_ptr = (*(self.e0.as_ptr())).clone();
217 let e1_ptr = (*(self.e1.as_ptr())).clone();
218 let e2_ptr = (*(self.e2.as_ptr())).clone();
219 let e3_ptr = (*(self.e3.as_ptr())).clone();
220 let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
221 $opt!(out_ptr,e0_ptr,e1_ptr,e2_ptr,e3_ptr);
222 }
223 }
224 fn out(&self) -> Value { self.out.to_value() }
225 fn to_string(&self) -> String { format!("{:#?}", self) }
226 }
227 #[cfg(feature = "compiler")]
228 impl<T> MechFunctionCompiler for $fxn<T>
229 where
230 T: ConstElem + CompileConst + AsValueKind
231 {
232 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
233 let name = format!("{}<{}>", stringify!($fxn), T::as_value_kind());
234 compile_quadop!(name, self.out, self.e0, self.e1, self.e2, self.e3, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
235 }
236 }
237 register_vertical_concatenate_fxn!($fxn);
238 };}
239
240#[cfg(feature = "matrixd")]
243struct VerticalConcatenateTwoArgs<T> {
244 e0: Box<dyn CopyMat<T>>,
245 e1: Box<dyn CopyMat<T>>,
246 out: Ref<DMatrix<T>>,
247}
248#[cfg(feature = "matrixd")]
249impl<T> MechFunctionFactory for VerticalConcatenateTwoArgs<T>
250where
251 T: Debug + Clone + Sync + Send + PartialEq + 'static +
252 ConstElem + CompileConst + AsValueKind,
253 Ref<DMatrix<T>>: ToValue
254{
255 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
256 match args {
257 FunctionArgs::Binary(out, arg0, arg1) => {
258 let e0: Box<dyn CopyMat<T>> = unsafe { arg0.get_copyable_matrix_unchecked::<T>() };
259 let e1: Box<dyn CopyMat<T>> = unsafe { arg1.get_copyable_matrix_unchecked::<T>() };
260 let out: Ref<DMatrix<T>> = unsafe { out.as_unchecked() }.clone();
261 Ok(Box::new(Self { e0, e1, out }))
262 },
263 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 2, found: args.len()}, None).with_compiler_loc())
264 }
265 }
266}
267#[cfg(feature = "matrixd")]
268impl<T> MechFunctionImpl for VerticalConcatenateTwoArgs<T>
269where
270 T: Debug + Clone + Sync + Send + PartialEq + 'static,
271 Ref<DMatrix<T>>: ToValue
272{
273 fn solve(&self) {
274 let offset = self.e0.copy_into_row_major(&self.out,0);
275 self.e1.copy_into_row_major(&self.out,offset);
276 }
277 fn out(&self) -> Value { self.out.to_value() }
278 fn to_string(&self) -> String { format!("VerticalConcatenateTwoArgs\n{:#?}", self.out) }
279}
280#[cfg(feature = "matrixd")]
281#[cfg(feature = "compiler")]
282impl<T> MechFunctionCompiler for VerticalConcatenateTwoArgs<T>
283where
284 T: ConstElem + CompileConst + AsValueKind + AsValueKind
285{
286 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
287 let mut registers = [0, 0, 0];
288
289 registers[0] = compile_register!(self.out, ctx);
290 registers[1] = compile_register_mat!(self.e0, ctx);
291 registers[2] = compile_register_mat!(self.e1, ctx);
292
293 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::VertCat));
294
295 ctx.emit_binop(
296 hash_str(&format!("VerticalConcatenateTwoArgs<{}>", T::as_value_kind())),
297 registers[0],
298 registers[1],
299 registers[2],
300 );
301
302 Ok(registers[0])
303 }
304}
305#[cfg(feature = "matrixd")]
306register_vertical_concatenate_fxn!(VerticalConcatenateTwoArgs);
307
308#[cfg(feature = "matrixd")]
311struct VerticalConcatenateThreeArgs<T> {
312 e0: Box<dyn CopyMat<T>>,
313 e1: Box<dyn CopyMat<T>>,
314 e2: Box<dyn CopyMat<T>>,
315 out: Ref<DMatrix<T>>,
316}
317#[cfg(feature = "matrixd")]
318impl<T> MechFunctionFactory for VerticalConcatenateThreeArgs<T>
319where
320 T: Debug + Clone + Sync + Send + PartialEq + 'static +
321 ConstElem + CompileConst + AsValueKind,
322 Ref<DMatrix<T>>: ToValue
323{
324 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
325 match args {
326 FunctionArgs::Ternary(out, arg0, arg1, arg2) => {
327 let e0: Box<dyn CopyMat<T>> = unsafe { arg0.get_copyable_matrix_unchecked::<T>() };
328 let e1: Box<dyn CopyMat<T>> = unsafe { arg1.get_copyable_matrix_unchecked::<T>() };
329 let e2: Box<dyn CopyMat<T>> = unsafe { arg2.get_copyable_matrix_unchecked::<T>() };
330 let out: Ref<DMatrix<T>> = unsafe { out.as_unchecked() }.clone();
331 Ok(Box::new(Self { e0, e1, e2, out }))
332 },
333 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 3, found: args.len()}, None).with_compiler_loc())
334 }
335 }
336}
337#[cfg(feature = "matrixd")]
338impl<T> MechFunctionImpl for VerticalConcatenateThreeArgs<T>
339where
340 T: Debug + Clone + Sync + Send + PartialEq + 'static,
341 Ref<DMatrix<T>>: ToValue
342{
343 fn solve(&self) {
344 let mut offset = self.e0.copy_into_row_major(&self.out,0);
345 offset += self.e1.copy_into_row_major(&self.out,offset);
346 self.e2.copy_into_row_major(&self.out,offset);
347 }
348 fn out(&self) -> Value { self.out.to_value() }
349 fn to_string(&self) -> String { format!("VerticalConcatenateThreeArgs\n{:#?}", self.out) }
350}
351#[cfg(feature = "matrixd")]
352#[cfg(feature = "compiler")]
353impl<T> MechFunctionCompiler for VerticalConcatenateThreeArgs<T>
354where
355 T: ConstElem + CompileConst + AsValueKind + AsValueKind
356{
357 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
358 let mut registers = [0, 0, 0, 0];
359
360 registers[0] = compile_register!(self.out, ctx);
361 registers[1] = compile_register_mat!(self.e0, ctx);
362 registers[2] = compile_register_mat!(self.e1, ctx);
363 registers[3] = compile_register_mat!(self.e2, ctx);
364
365 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::VertCat));
366
367 ctx.emit_ternop(
368 hash_str(&format!("VerticalConcatenateThreeArgs<{}>", T::as_value_kind())),
369 registers[0],
370 registers[1],
371 registers[2],
372 registers[3],
373 );
374 Ok(registers[0])
375 }
376}
377#[cfg(feature = "matrixd")]
378register_vertical_concatenate_fxn!(VerticalConcatenateThreeArgs);
379
380#[cfg(feature = "matrixd")]
383struct VerticalConcatenateFourArgs<T> {
384 e0: Box<dyn CopyMat<T>>,
385 e1: Box<dyn CopyMat<T>>,
386 e2: Box<dyn CopyMat<T>>,
387 e3: Box<dyn CopyMat<T>>,
388 out: Ref<DMatrix<T>>,
389}
390#[cfg(feature = "matrixd")]
391impl<T> MechFunctionFactory for VerticalConcatenateFourArgs<T>
392where
393 T: Debug + Clone + Sync + Send + PartialEq + 'static +
394 ConstElem + CompileConst + AsValueKind,
395 Ref<DMatrix<T>>: ToValue
396{
397 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
398 match args {
399 FunctionArgs::Quaternary(out, arg0, arg1, arg2, arg3) => {
400 let e0: Box<dyn CopyMat<T>> = unsafe { arg0.get_copyable_matrix_unchecked::<T>() };
401 let e1: Box<dyn CopyMat<T>> = unsafe { arg1.get_copyable_matrix_unchecked::<T>() };
402 let e2: Box<dyn CopyMat<T>> = unsafe { arg2.get_copyable_matrix_unchecked::<T>() };
403 let e3: Box<dyn CopyMat<T>> = unsafe { arg3.get_copyable_matrix_unchecked::<T>() };
404 let out: Ref<DMatrix<T>> = unsafe { out.as_unchecked() }.clone();
405 Ok(Box::new(Self { e0, e1, e2, e3, out }))
406 },
407 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 4, found: args.len()}, None).with_compiler_loc())
408 }
409 }
410}
411#[cfg(feature = "matrixd")]
412impl<T> MechFunctionImpl for VerticalConcatenateFourArgs<T>
413where
414 T: Debug + Clone + Sync + Send + PartialEq + 'static,
415 Ref<DMatrix<T>>: ToValue
416{
417 fn solve(&self) {
418 let mut offset = self.e0.copy_into_row_major(&self.out,0);
419 offset += self.e1.copy_into_row_major(&self.out,offset);
420 offset += self.e2.copy_into_row_major(&self.out,offset);
421 self.e3.copy_into_row_major(&self.out,offset);
422
423 }
424 fn out(&self) -> Value { self.out.to_value() }
425 fn to_string(&self) -> String { format!("VerticalConcatenateFourArgs\n{:#?}", self.out) }
426}
427#[cfg(feature = "matrixd")]
428#[cfg(feature = "compiler")]
429impl<T> MechFunctionCompiler for VerticalConcatenateFourArgs<T>
430where
431 T: ConstElem + CompileConst + AsValueKind
432{
433 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
434let mut registers = [0, 0, 0, 0, 0];
435
436 registers[0] = compile_register!(self.out, ctx);
437 registers[1] = compile_register_mat!(self.e0, ctx);
438 registers[2] = compile_register_mat!(self.e1, ctx);
439 registers[3] = compile_register_mat!(self.e2, ctx);
440 registers[4] = compile_register_mat!(self.e3, ctx);
441
442 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::VertCat));
443
444 ctx.emit_quadop(
445 hash_str(&format!("VerticalConcatenateFourArgs<{}>", T::as_value_kind())),
446 registers[0],
447 registers[1],
448 registers[2],
449 registers[3],
450 registers[4],
451 );
452 Ok(registers[0])
453 }
454}
455#[cfg(feature = "matrixd")]
456register_vertical_concatenate_fxn!(VerticalConcatenateFourArgs);
457
458#[cfg(feature = "matrixd")]
461struct VerticalConcatenateNArgs<T> {
462 e0: Vec<Box<dyn CopyMat<T>>>,
463 out: Ref<DMatrix<T>>,
464}
465#[cfg(feature = "matrixd")]
466impl<T> MechFunctionFactory for VerticalConcatenateNArgs<T>
467where
468 T: Debug + Clone + Sync + Send + PartialEq + 'static +
469 ConstElem + CompileConst + AsValueKind,
470 Ref<DMatrix<T>>: ToValue
471{
472 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
473 match args {
474 FunctionArgs::Variadic(out, arg0) => {
475 let mut e0: Vec<Box<dyn CopyMat<T>>> = Vec::new();
476 for arg in arg0 {
477 let mat: Box<dyn CopyMat<T>> = unsafe { arg.get_copyable_matrix_unchecked::<T>() };
478 e0.push(mat);
479 }
480 let out: Ref<DMatrix<T>> = unsafe { out.as_unchecked() }.clone();
481 Ok(Box::new(Self { e0, out }))
482 },
483 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 0, found: args.len()}, None).with_compiler_loc())
484 }
485 }
486}
487#[cfg(feature = "matrixd")]
488impl<T> MechFunctionImpl for VerticalConcatenateNArgs<T>
489where
490 T: Debug + Clone + Sync + Send + PartialEq + 'static,
491 Ref<DMatrix<T>>: ToValue
492{
493 fn solve(&self) {
494 let mut offset = 0;
495 for e in &self.e0 {
496 offset += e.copy_into_row_major(&self.out,offset);
497 }
498 }
499 fn out(&self) -> Value { self.out.to_value() }
500 fn to_string(&self) -> String { format!("VerticalConcatenateNArgs\n{:#?}", self.out) }
501}
502#[cfg(feature = "matrixd")]
503#[cfg(feature = "compiler")]
504impl<T> MechFunctionCompiler for VerticalConcatenateNArgs<T>
505where
506 T: ConstElem + CompileConst + AsValueKind
507{
508 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
509 let mut registers = [0, 0];
510
511 registers[0] = compile_register!(self.out, ctx);
512
513 let mut mat_regs = Vec::new();
514 for e in &self.e0 {
515 let e_addr = e.addr();
516 let e_reg = ctx.alloc_register_for_ptr(e_addr);
517 let e_const_id = e.compile_const_mat(ctx).unwrap();
518 ctx.emit_const_load(e_reg, e_const_id);
519 mat_regs.push(e_reg);
520 }
521 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::HorzCat));
522 ctx.emit_varop(
523 hash_str(&format!("VerticalConcatenateNArgs<{}>", T::as_value_kind())),
524 registers[0],
525 mat_regs,
526 );
527 Ok(registers[0])
528 }
529}
530#[cfg(feature = "matrixd")]
531register_vertical_concatenate_fxn!(VerticalConcatenateNArgs);
532
533macro_rules! vertical_concatenate {
536 ($name:ident, $vec_size:expr) => {
537 paste!{
538 #[derive(Debug)]
539 struct $name<T> {
540 out: Ref<[<$vec_size>]<T>>,
541 }
542 impl<T> MechFunctionFactory for $name<T>
543 where
544 T: Debug + Clone + Sync + Send + PartialEq + 'static +
545 ConstElem + CompileConst + AsValueKind,
546 Ref<[<$vec_size>]<T>>: ToValue
547 {
548 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
549 match args {
550 FunctionArgs::Unary(out, _arg0) => {
551 let out: Ref<[<$vec_size>]<T>> = unsafe { out.as_unchecked() }.clone();
552 Ok(Box::new(Self { out }))
553 },
554 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 1, found: args.len()}, None).with_compiler_loc())
555 }
556 }
557 }
558 impl<T> MechFunctionImpl for $name<T>
559 where
560 T: Debug + Clone + Sync + Send + PartialEq + 'static,
561 Ref<[<$vec_size>]<T>>: ToValue
562 {
563 fn solve(&self) {}
564 fn out(&self) -> Value { self.out.to_value() }
565 fn to_string(&self) -> String { format!("{:#?}", self) }
566 }
567 #[cfg(feature = "compiler")]
568 impl<T> MechFunctionCompiler for $name<T>
569 where
570 T: ConstElem + CompileConst + AsValueKind + AsValueKind
571 {
572 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
573 let name = format!("{}<{}>", stringify!($name), T::as_value_kind());
574 compile_unop!(name, self.out, self.out, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
575 }
576 }
577 register_vertical_concatenate_fxn!($name);
578 }
579 };}
580
581#[cfg(feature = "vectord")]
584struct VerticalConcatenateVD2<T> {
585 e0: Box<dyn CopyMat<T>>,
586 e1: Box<dyn CopyMat<T>>,
587 out: Ref<DVector<T>>,
588}
589#[cfg(feature = "vectord")]
590impl<T> MechFunctionFactory for VerticalConcatenateVD2<T>
591where
592 T: Debug + Clone + Sync + Send + PartialEq + 'static +
593 ConstElem + CompileConst + AsValueKind,
594 Ref<DVector<T>>: ToValue
595{
596 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
597 match args {
598 FunctionArgs::Binary(out, arg0, arg1) => {
599 let e0: Box<dyn CopyMat<T>> = unsafe { arg0.get_copyable_matrix_unchecked::<T>() };
600 let e1: Box<dyn CopyMat<T>> = unsafe { arg1.get_copyable_matrix_unchecked::<T>() };
601 let out: Ref<DVector<T>> = unsafe { out.as_unchecked() }.clone();
602 Ok(Box::new(Self { e0, e1, out }))
603 },
604 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 2, found: args.len()}, None).with_compiler_loc())
605 }
606 }
607}
608#[cfg(feature = "vectord")]
609impl<T> MechFunctionImpl for VerticalConcatenateVD2<T>
610where
611 T: Debug + Clone + Sync + Send + PartialEq + 'static,
612 Ref<DVector<T>>: ToValue
613{
614 fn solve(&self) {
615 let mut offset = self.e0.copy_into_v(&self.out,0);
616 self.e1.copy_into_v(&self.out,offset);
617 }
618 fn out(&self) -> Value { self.out.to_value() }
619 fn to_string(&self) -> String { format!("VerticalConcatenateVD2\n{:#?}", self.out) }
620}
621#[cfg(feature = "vectord")]
622#[cfg(feature = "compiler")]
623impl<T> MechFunctionCompiler for VerticalConcatenateVD2<T>
624where
625 T: ConstElem + CompileConst + AsValueKind
626{
627 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
628 let mut registers = [0, 0, 0];
629
630 registers[0] = compile_register!(self.out, ctx);
631
632 let lhs_addr = self.e0.addr();
633 let lhs_reg = ctx.alloc_register_for_ptr(lhs_addr);
634 let lhs_const_id = self.e0.compile_const_mat(ctx).unwrap();
635 ctx.emit_const_load(lhs_reg, lhs_const_id);
636 registers[1] = lhs_reg;
637
638 let rhs_addr = self.e1.addr();
639 let rhs_reg = ctx.alloc_register_for_ptr(rhs_addr);
640 let rhs_const_id = self.e1.compile_const_mat(ctx).unwrap();
641 ctx.emit_const_load(rhs_reg, rhs_const_id);
642 registers[2] = rhs_reg;
643
644 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::HorzCat));
645
646 ctx.emit_binop(
647 hash_str(&format!("VerticalConcatenateVD2<{}>", T::as_value_kind())),
648 registers[0],
649 registers[1],
650 registers[2],
651 );
652
653 Ok(registers[0])
654 }
655}
656#[cfg(feature = "vectord")]
657register_vertical_concatenate_fxn!(VerticalConcatenateVD2);
658
659#[cfg(feature = "vectord")]
662struct VerticalConcatenateVD3<T> {
663 e0: Box<dyn CopyMat<T>>,
664 e1: Box<dyn CopyMat<T>>,
665 e2: Box<dyn CopyMat<T>>,
666 out: Ref<DVector<T>>,
667}
668#[cfg(feature = "vectord")]
669impl<T> MechFunctionFactory for VerticalConcatenateVD3<T>
670where
671 T: Debug + Clone + Sync + Send + PartialEq + 'static +
672 ConstElem + CompileConst + AsValueKind,
673 Ref<DVector<T>>: ToValue
674{
675 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
676 match args {
677 FunctionArgs::Ternary(out, arg0, arg1, arg2) => {
678 let e0: Box<dyn CopyMat<T>> = unsafe { arg0.get_copyable_matrix_unchecked::<T>() };
679 let e1: Box<dyn CopyMat<T>> = unsafe { arg1.get_copyable_matrix_unchecked::<T>() };
680 let e2: Box<dyn CopyMat<T>> = unsafe { arg2.get_copyable_matrix_unchecked::<T>() };
681 let out: Ref<DVector<T>> = unsafe { out.as_unchecked() }.clone();
682 Ok(Box::new(Self { e0, e1, e2, out }))
683 },
684 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 3, found: args.len()}, None).with_compiler_loc())
685 }
686 }
687}
688#[cfg(feature = "vectord")]
689impl<T> MechFunctionImpl for VerticalConcatenateVD3<T>
690where
691 T: Debug + Clone + Sync + Send + PartialEq + 'static,
692 Ref<DVector<T>>: ToValue
693{
694 fn solve(&self) {
695 let mut offset = self.e0.copy_into_v(&self.out,0);
696 offset += self.e1.copy_into_v(&self.out,offset);
697 self.e2.copy_into_v(&self.out,offset);
698 }
699 fn out(&self) -> Value { self.out.to_value() }
700 fn to_string(&self) -> String { format!("VerticalConcatenateVD3\n{:#?}", self.out) }
701}
702#[cfg(feature = "vectord")]
703#[cfg(feature = "compiler")]
704impl<T> MechFunctionCompiler for VerticalConcatenateVD3<T>
705where
706 T: ConstElem + CompileConst + AsValueKind
707{
708 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
709 let mut registers = [0, 0, 0, 0];
710
711 registers[0] = compile_register!(self.out, ctx);
712 registers[1] = compile_register_mat!(self.e0, ctx);
713 registers[2] = compile_register_mat!(self.e1, ctx);
714 registers[3] = compile_register_mat!(self.e2, ctx);
715
716 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::HorzCat));
717
718 ctx.emit_ternop(
719 hash_str(&format!("VerticalConcatenateVD3<{}>", T::as_value_kind())),
720 registers[0],
721 registers[1],
722 registers[2],
723 registers[3],
724 );
725 Ok(registers[0])
726 }
727}
728#[cfg(feature = "vectord")]
729register_vertical_concatenate_fxn!(VerticalConcatenateVD3);
730
731#[cfg(feature = "vectord")]
734struct VerticalConcatenateVD4<T> {
735 e0: Box<dyn CopyMat<T>>,
736 e1: Box<dyn CopyMat<T>>,
737 e2: Box<dyn CopyMat<T>>,
738 e3: Box<dyn CopyMat<T>>,
739 out: Ref<DVector<T>>,
740}
741#[cfg(feature = "vectord")]
742impl<T> MechFunctionFactory for VerticalConcatenateVD4<T>
743where
744 T: Debug + Clone + Sync + Send + PartialEq + 'static +
745 ConstElem + CompileConst + AsValueKind,
746 Ref<DVector<T>>: ToValue
747{
748 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
749 match args {
750 FunctionArgs::Quaternary(out, arg0, arg1, arg2, arg3) => {
751 let e0: Box<dyn CopyMat<T>> = unsafe { arg0.get_copyable_matrix_unchecked::<T>() };
752 let e1: Box<dyn CopyMat<T>> = unsafe { arg1.get_copyable_matrix_unchecked::<T>() };
753 let e2: Box<dyn CopyMat<T>> = unsafe { arg2.get_copyable_matrix_unchecked::<T>() };
754 let e3: Box<dyn CopyMat<T>> = unsafe { arg3.get_copyable_matrix_unchecked::<T>() };
755 let out: Ref<DVector<T>> = unsafe { out.as_unchecked() }.clone();
756 Ok(Box::new(Self { e0, e1, e2, e3, out }))
757 },
758 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 4, found: args.len()}, None).with_compiler_loc())
759 }
760 }
761}
762#[cfg(feature = "vectord")]
763impl<T> MechFunctionImpl for VerticalConcatenateVD4<T>
764where
765 T: Debug + Clone + Sync + Send + PartialEq + 'static,
766 Ref<DVector<T>>: ToValue
767{
768 fn solve(&self) {
769 let mut offset = self.e0.copy_into_v(&self.out,0);
770 offset += self.e1.copy_into_v(&self.out,offset);
771 offset += self.e2.copy_into_v(&self.out,offset);
772 self.e3.copy_into_v(&self.out,offset);
773 }
774 fn out(&self) -> Value { self.out.to_value() }
775 fn to_string(&self) -> String { format!("VerticalConcatenateVD3\n{:#?}", self.out) }
776}
777#[cfg(feature = "vectord")]
778#[cfg(feature = "compiler")]
779impl<T> MechFunctionCompiler for VerticalConcatenateVD4<T>
780where
781 T: ConstElem + CompileConst + AsValueKind
782{
783 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
784 let mut registers = [0, 0, 0, 0, 0];
785
786 registers[0] = compile_register!(self.out, ctx);
787 registers[1] = compile_register_mat!(self.e0, ctx);
788 registers[2] = compile_register_mat!(self.e1, ctx);
789 registers[3] = compile_register_mat!(self.e2, ctx);
790 registers[4] = compile_register_mat!(self.e3, ctx);
791
792 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::HorzCat));
793
794 ctx.emit_quadop(
795 hash_str(&format!("VerticalConcatenateVD4<{}>", T::as_value_kind())),
796 registers[0],
797 registers[1],
798 registers[2],
799 registers[3],
800 registers[4],
801 );
802 Ok(registers[0])
803 }
804}
805#[cfg(feature = "vectord")]
806register_vertical_concatenate_fxn!(VerticalConcatenateVD4);
807
808#[cfg(feature = "vectord")]
811struct VerticalConcatenateVDN<T> {
812 scalar: Vec<(Ref<T>,usize)>,
813 matrix: Vec<(Box<dyn CopyMat<T>>,usize)>,
814 out: Ref<DVector<T>>,
815}
816#[cfg(feature = "vectord")]
817impl<T> MechFunctionFactory for VerticalConcatenateVDN<T>
818where
819 T: Debug + Clone + Sync + Send + PartialEq + 'static +
820 ConstElem + CompileConst + AsValueKind,
821 Ref<DVector<T>>: ToValue
822{
823 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
824 match args {
825 FunctionArgs::Variadic(out, vargs) => {
826 let mut scalar: Vec<(Ref<T>,usize)> = Vec::new();
827 let mut matrix: Vec<(Box<dyn CopyMat<T>>,usize)> = Vec::new();
828 for (i, arg) in vargs.into_iter().enumerate() {
829 let kind = arg.kind();
830 if arg.is_scalar() {
831 let scalar_ref = unsafe { arg.as_unchecked::<T>() };
832 scalar.push((scalar_ref.clone(), i));
833 } else {
834 let mat_ref: Box<dyn CopyMat<T>> = unsafe { arg.get_copyable_matrix_unchecked::<T>() };
835 matrix.push((mat_ref, i));
836 }
837 }
838 let out: Ref<DVector<T>> = unsafe { out.as_unchecked() }.clone();
839 Ok(Box::new(Self { scalar, matrix, out }))
840 },
841 _ => Err(MechError2::new(IncorrectNumberOfArguments{expected: 0, found: args.len()}, None).with_compiler_loc())
842 }
843 }
844}
845#[cfg(feature = "vectord")]
846impl<T> MechFunctionImpl for VerticalConcatenateVDN<T>
847where
848 T: Debug + Clone + Sync + Send + PartialEq + 'static,
849 Ref<DVector<T>>: ToValue
850{
851 fn solve(&self) {
852 unsafe {
853 let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
854 for (e,i) in &self.matrix {
855 e.copy_into_v(&self.out,*i);
856 }
857 for (e,i) in &self.scalar {
858 out_ptr[*i] = e.borrow().clone();
859 }
860 }
861 }
862 fn out(&self) -> Value { self.out.to_value() }
863 fn to_string(&self) -> String { format!("VerticalConcatenateVDN\n{:#?}", self.out) }
864}
865#[cfg(feature = "vectord")]
866#[cfg(feature = "compiler")]
867impl<T> MechFunctionCompiler for VerticalConcatenateVDN<T>
868where
869 T: ConstElem + CompileConst + AsValueKind
870{
871 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
872 let mut registers = [0, 0];
873
874 registers[0] = compile_register!(self.out, ctx);
875
876 let mut mat_regs = Vec::new();
877 for (e,_) in &self.matrix {
878 mat_regs.push(compile_register_mat!(e, ctx));
879 }
880 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::HorzCat));
881 ctx.emit_varop(
882 hash_str(&format!("VerticalConcatenateVDN<{}>", T::as_value_kind())),
883 registers[0],
884 mat_regs,
885 );
886 Ok(registers[0])
887 }
888}
889#[cfg(feature = "vectord")]
890register_vertical_concatenate_fxn!(VerticalConcatenateVDN);
891
892#[cfg(feature = "matrix1")]
895#[derive(Debug)]
896struct VerticalConcatenateS1<T> {
897 out: Ref<Matrix1<T>>,
898}
899#[cfg(feature = "matrix1")]
900impl<T> MechFunctionFactory for VerticalConcatenateS1<T>
901where
902 T: Debug + Clone + Sync + Send + PartialEq + 'static +
903 ConstElem + CompileConst + AsValueKind,
904 Ref<Matrix1<T>>: ToValue
905{
906 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
907 match args {
908 FunctionArgs::Unary(out, _arg0) => {
909 let out: Ref<Matrix1<T>> = unsafe { out.as_unchecked() }.clone();
910 Ok(Box::new(Self { out }))
911 },
912 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("VerticalConcatenateS1 requires 1 argument, got {:?}", args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
913 }
914 }
915}
916#[cfg(feature = "matrix1")]
917impl<T> MechFunctionImpl for VerticalConcatenateS1<T>
918where
919 T: Debug + Clone + Sync + Send + PartialEq + 'static,
920 Ref<Matrix1<T>>: ToValue
921{
922 fn solve(&self) {}
923 fn out(&self) -> Value { self.out.to_value() }
924 fn to_string(&self) -> String { format!("{:#?}", self) }
925}
926
927#[cfg(all(feature = "matrix1", feature = "compiler"))]
928impl<T> MechFunctionCompiler for VerticalConcatenateS1<T>
929where
930 T: ConstElem + CompileConst + AsValueKind
931{
932 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
933 let name = format!("VerticalConcatenateS1<{}>", T::as_value_kind());
934 compile_nullop!(name, self.out, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
935 }
936}
937#[cfg(feature = "matrix1")]
938register_vertical_concatenate_fxn!(VerticalConcatenateS1);
939
940#[cfg(feature = "vector2")]
943vertical_concatenate!(VerticalConcatenateS2,Vector2);
944
945#[cfg(feature = "vector3")]
948vertical_concatenate!(VerticalConcatenateS3,Vector3);
949
950#[cfg(feature = "vector4")]
953vertical_concatenate!(VerticalConcatenateS4,Vector4);
954
955#[cfg(feature = "vector2")]
958vertical_concatenate!(VerticalConcatenateV2,Vector2);
959
960#[cfg(feature = "vector3")]
963vertical_concatenate!(VerticalConcatenateV3,Vector3);
964
965#[cfg(feature = "vector4")]
968vertical_concatenate!(VerticalConcatenateV4,Vector4);
969
970#[cfg(feature = "matrix2")]
973vertical_concatenate!(VerticalConcatenateM2,Matrix2);
974
975#[cfg(feature = "matrix3")]
978vertical_concatenate!(VerticalConcatenateM3,Matrix3);
979
980#[cfg(feature = "matrix2x3")]
983vertical_concatenate!(VerticalConcatenateM2x3,Matrix2x3);
984
985#[cfg(feature = "matrix3x2")]
988vertical_concatenate!(VerticalConcatenateM3x2,Matrix3x2);
989
990#[cfg(feature = "matrix4")]
993vertical_concatenate!(VerticalConcatenateM4,Matrix4);
994
995#[cfg(feature = "matrixd")]
998vertical_concatenate!(VerticalConcatenateMD,DMatrix);
999
1000#[cfg(feature = "vectord")]
1003vertical_concatenate!(VerticalConcatenateVD,DVector);
1004
1005#[cfg(feature = "vectord")]
1008#[derive(Debug)]
1009struct VerticalConcatenateSD<T> {
1010 out: Ref<DVector<T>>,
1011}
1012#[cfg(feature = "vectord")]
1013impl<T> MechFunctionFactory for VerticalConcatenateSD<T>
1014where
1015 T: Debug + Clone + Sync + Send + PartialEq + 'static +
1016 ConstElem + CompileConst + AsValueKind,
1017 Ref<DVector<T>>: ToValue
1018{
1019 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
1020 match args {
1021 FunctionArgs::Unary(out, _arg0) => {
1022 let out: Ref<DVector<T>> = unsafe { out.as_unchecked() }.clone();
1023 Ok(Box::new(Self { out }))
1024 },
1025 _ => Err(MechError2::new(
1026 IncorrectNumberOfArguments { expected: 1, found: args.len() },
1027 None
1028 ).with_compiler_loc()
1029 ),
1030 }
1031 }
1032}
1033#[cfg(feature = "vectord")]
1034impl<T> MechFunctionImpl for VerticalConcatenateSD<T>
1035where
1036 T: Debug + Clone + Sync + Send + PartialEq + 'static,
1037 Ref<DVector<T>>: ToValue
1038{
1039 fn solve(&self) { }
1040 fn out(&self) -> Value { self.out.to_value() }
1041 fn to_string(&self) -> String { format!("{:#?}", self) }
1042}
1043#[cfg(all(feature = "vectord", feature = "compiler"))]
1044impl<T> MechFunctionCompiler for VerticalConcatenateSD<T>
1045where
1046 T: ConstElem + CompileConst + AsValueKind
1047{
1048 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1049 let name = format!("VerticalConcatenateSD<{}>", T::as_value_kind());
1050 compile_nullop!(name, self.out, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
1051 }
1052}
1053#[cfg(feature = "vectord")]
1054register_vertical_concatenate_fxn!(VerticalConcatenateSD);
1055
1056macro_rules! vertcat_m1m1 {
1059 ($out:expr, $e0:expr, $e1:expr) => {
1060 $out[0] = $e0[0].clone();
1061 $out[1] = $e1[0].clone();
1062 };}
1063#[cfg(all(feature = "matrix1", feature = "vector2"))]
1064vertcat_two_args!(VerticalConcatenateM1M1,Matrix1,Matrix1,Vector2,vertcat_m1m1);
1065
1066macro_rules! vertcat_r2r2 {
1069 ($out:expr, $e0:expr, $e1:expr) => {
1070 $out[0] = $e0[0].clone();
1071 $out[1] = $e0[1].clone();
1072 $out[2] = $e1[0].clone();
1073 $out[3] = $e1[1].clone();
1074 };}
1075#[cfg(all(feature = "vector2", feature = "vector4"))]
1076vertcat_two_args!(VerticalConcatenateV2V2,Vector2,Vector2,Vector4,vertcat_r2r2);
1077
1078macro_rules! vertcat_m1r3 {
1081 ($out:expr, $e0:expr, $e1:expr) => {
1082 $out[0] = $e0[0].clone();
1083 $out[1] = $e1[0].clone();
1084 $out[2] = $e1[1].clone();
1085 $out[3] = $e1[2].clone();
1086 };}
1087#[cfg(all(feature = "matrix1", feature = "vector3", feature = "vector4"))]
1088vertcat_two_args!(VerticalConcatenateM1V3,Matrix1,Vector3,Vector4,vertcat_m1r3);
1089
1090macro_rules! vertcat_r3m1 {
1093 ($out:expr, $e0:expr, $e1:expr) => {
1094 $out[0] = $e0[0].clone();
1095 $out[1] = $e0[1].clone();
1096 $out[2] = $e0[2].clone();
1097 $out[3] = $e1[0].clone();
1098 };}
1099#[cfg(all(feature = "vector3", feature = "matrix1", feature = "vector4"))]
1100vertcat_two_args!(VerticalConcatenateV3M1,Vector3,Matrix1,Vector4,vertcat_r3m1);
1101
1102macro_rules! vertcat_m1r2 {
1105 ($out:expr, $e0:expr, $e1:expr) => {
1106 $out[0] = $e0[0].clone();
1107 $out[1] = $e1[0].clone();
1108 $out[2] = $e1[1].clone();
1109 };
1110}
1111#[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector3"))]
1112vertcat_two_args!(VerticalConcatenateM1V2, Matrix1, Vector2, Vector3, vertcat_m1r2);
1113
1114macro_rules! vertcat_r2m1 {
1117 ($out:expr, $e0:expr, $e1:expr) => {
1118 $out[0] = $e0[0].clone();
1119 $out[1] = $e0[1].clone();
1120 $out[2] = $e1[0].clone();
1121 };
1122}
1123#[cfg(all(feature = "vector2", feature = "matrix1", feature = "vector3"))]
1124vertcat_two_args!(VerticalConcatenateV2M1, Vector2, Matrix1, Vector3, vertcat_r2m1);
1125
1126macro_rules! vertcat_m1m1m1 {
1129 ($out:expr, $e0:expr,$e1:expr,$e2:expr) => {
1130 $out[0] = $e0[0].clone();
1131 $out[1] = $e1[0].clone();
1132 $out[2] = $e2[0].clone();
1133 };
1134}
1135#[cfg(all(feature = "matrix1", feature = "vector3"))]
1136vertcat_three_args!(VerticalConcatenateM1M1M1,Matrix1,Matrix1,Matrix1,Vector3, vertcat_m1m1m1);
1137
1138macro_rules! vertcat_m1m1v2 {
1141 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
1142 $out[0] = $e0[0].clone();
1143 $out[1] = $e1[0].clone();
1144 $out[2] = $e2[0].clone();
1145 $out[3] = $e2[1].clone();
1146 };
1147}
1148#[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector4"))]
1149vertcat_three_args!(VerticalConcatenateM1M1V2, Matrix1, Matrix1, Vector2, Vector4, vertcat_m1m1v2);
1150
1151macro_rules! vertcat_m1r2m1 {
1154 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
1155 $out[0] = $e0[0].clone();
1156 $out[1] = $e1[0].clone();
1157 $out[2] = $e1[1].clone();
1158 $out[3] = $e2[0].clone();
1159 };
1160}
1161#[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector4"))]
1162vertcat_three_args!(VerticalConcatenateM1V2M1, Matrix1, Vector2, Matrix1, Vector4, vertcat_m1r2m1);
1163
1164macro_rules! vertcat_r2m1m1 {
1167 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
1168 $out[0] = $e0[0].clone();
1169 $out[1] = $e0[1].clone();
1170 $out[2] = $e1[0].clone();
1171 $out[3] = $e2[0].clone();
1172 };
1173}
1174#[cfg(all(feature = "vector2", feature = "matrix1", feature = "vector4"))]
1175vertcat_three_args!(VerticalConcatenateV2M1M1, Vector2, Matrix1, Matrix1, Vector4, vertcat_r2m1m1);
1176
1177#[cfg(all(feature = "matrix1", feature = "vector4"))]
1180#[derive(Debug)]
1181struct VerticalConcatenateM1M1M1M1<T> {
1182 e0: Ref<Matrix1<T>>,
1183 e1: Ref<Matrix1<T>>,
1184 e2: Ref<Matrix1<T>>,
1185 e3: Ref<Matrix1<T>>,
1186 out: Ref<Vector4<T>>,
1187}
1188#[cfg(all(feature = "matrix1", feature = "vector4"))]
1189impl<T> MechFunctionFactory for VerticalConcatenateM1M1M1M1<T>
1190where
1191 T: Debug + Clone + Sync + Send + PartialEq + 'static +
1192 ConstElem + CompileConst + AsValueKind,
1193 Ref<Vector4<T>>: ToValue
1194{
1195 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
1196 match args {
1197 FunctionArgs::Quaternary(out, arg0, arg1, arg2, arg3) => {
1198 let e0: Ref<Matrix1<T>> = unsafe { arg0.as_unchecked() }.clone();
1199 let e1: Ref<Matrix1<T>> = unsafe { arg1.as_unchecked() }.clone();
1200 let e2: Ref<Matrix1<T>> = unsafe { arg2.as_unchecked() }.clone();
1201 let e3: Ref<Matrix1<T>> = unsafe { arg3.as_unchecked() }.clone();
1202 let out: Ref<Vector4<T>> = unsafe { out.as_unchecked() }.clone();
1203 Ok(Box::new(Self { e0, e1, e2, e3, out }))
1204 },
1205 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("VerticalConcatenateM1M1M1M1 requires 4 arguments, got {:?}", args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
1206 }
1207 }
1208}
1209#[cfg(all(feature = "matrix1", feature = "vector4"))]
1210impl<T> MechFunctionImpl for VerticalConcatenateM1M1M1M1<T>
1211where
1212 T: Debug + Clone + Sync + Send + PartialEq + 'static,
1213 Ref<Vector4<T>>: ToValue
1214{
1215 fn solve(&self) {
1216 unsafe {
1217 let e0_ptr = (*(self.e0.as_ptr())).clone();
1218 let e1_ptr = (*(self.e1.as_ptr())).clone();
1219 let e2_ptr = (*(self.e2.as_ptr())).clone();
1220 let e3_ptr = (*(self.e3.as_ptr())).clone();
1221 let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
1222 out_ptr[0] = e0_ptr[0].clone();
1223 out_ptr[1] = e1_ptr[0].clone();
1224 out_ptr[2] = e2_ptr[0].clone();
1225 out_ptr[3] = e3_ptr[0].clone();
1226 }
1227 }
1228 fn out(&self) -> Value { self.out.to_value() }
1229 fn to_string(&self) -> String { format!("{:#?}", self) }
1230}
1231#[cfg(all(feature = "matrix1", feature = "vector4", feature = "compiler"))]
1232impl<T> MechFunctionCompiler for VerticalConcatenateM1M1M1M1<T>
1233where
1234 T: ConstElem + CompileConst + AsValueKind
1235{
1236 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1237 let name = format!("VerticalConcatenateM1M1M1M1<{}>", T::as_value_kind());
1238 compile_quadop!(name, self.out, self.e0, self.e1, self.e2, self.e3, ctx, FeatureFlag::Builtin(FeatureKind::VertCat));
1239 }
1240}
1241#[cfg(all(feature = "matrix1", feature = "vector4"))]
1242register_vertical_concatenate_fxn!(VerticalConcatenateM1M1M1M1);
1243
1244macro_rules! vertcat_r2r2 {
1247 ($out:expr, $e0:expr, $e1:expr) => {
1248 $out[0] = $e0[0].clone();
1249 $out[2] = $e0[1].clone();
1250 $out[1] = $e1[0].clone();
1251 $out[3] = $e1[1].clone();
1252 };
1253}
1254#[cfg(all(feature = "row_vector2", feature = "matrix2"))]
1255vertcat_two_args!(VerticalConcatenateR2R2, RowVector2, RowVector2, Matrix2, vertcat_r2r2);
1256
1257macro_rules! vertcat_r3r3 {
1260 ($out:expr, $e0:expr, $e1:expr) => {
1261 $out[0] = $e0[0].clone();
1262 $out[2] = $e0[1].clone();
1263 $out[4] = $e0[2].clone();
1264 $out[1] = $e1[0].clone();
1265 $out[3] = $e1[1].clone();
1266 $out[5] = $e1[2].clone();
1267 };
1268}
1269#[cfg(all(feature = "row_vector3", feature = "matrix2x3"))]
1270vertcat_two_args!(VerticalConcatenateR3R3, RowVector3, RowVector3, Matrix2x3, vertcat_r3r3);
1271
1272macro_rules! vertcat_r2m2 {
1275 ($out:expr, $e0:expr, $e1:expr) => {
1276 $out[0] = $e0[0].clone();
1277 $out[3] = $e0[1].clone();
1278 $out[1] = $e1[0].clone();
1279 $out[2] = $e1[1].clone();
1280 $out[4] = $e1[2].clone();
1281 $out[5] = $e1[3].clone();
1282 };
1283}
1284#[cfg(all(feature = "row_vector2", feature = "matrix2", feature = "matrix3x2"))]
1285vertcat_two_args!(VerticalConcatenateR2M2, RowVector2, Matrix2, Matrix3x2, vertcat_r2m2);
1286
1287macro_rules! vertcat_m2r2 {
1290 ($out:expr, $e0:expr, $e1:expr) => {
1291 $out[0] = $e0[0].clone();
1292 $out[1] = $e0[1].clone();
1293 $out[3] = $e0[2].clone();
1294 $out[4] = $e0[3].clone();
1295 $out[2] = $e1[0].clone();
1296 $out[5] = $e1[1].clone();
1297 };
1298}
1299#[cfg(all(feature = "matrix2", feature = "row_vector2", feature = "matrix3x2"))]
1300vertcat_two_args!(VerticalConcatenateM2R2, Matrix2, RowVector2, Matrix3x2, vertcat_m2r2);
1301
1302macro_rules! vertcat_m2x3r3 {
1305 ($out:expr, $e0:expr, $e1:expr) => {
1306 $out[0] = $e0[0].clone();
1307 $out[1] = $e0[1].clone();
1308 $out[3] = $e0[2].clone();
1309 $out[4] = $e0[3].clone();
1310 $out[6] = $e0[4].clone();
1311 $out[7] = $e0[5].clone();
1312 $out[2] = $e1[0].clone();
1313 $out[5] = $e1[1].clone();
1314 $out[8] = $e1[2].clone();
1315 };
1316}
1317#[cfg(all(feature = "matrix2x3", feature = "row_vector3", feature = "matrix3"))]
1318vertcat_two_args!(VerticalConcatenateM2x3R3, Matrix2x3, RowVector3, Matrix3, vertcat_m2x3r3);
1319
1320macro_rules! vertcat_r3m2x3 {
1323 ($out:expr, $e0:expr, $e1:expr) => {
1324 $out[0] = $e0[0].clone();
1325 $out[3] = $e0[1].clone();
1326 $out[6] = $e0[2].clone();
1327 $out[1] = $e1[0].clone();
1328 $out[2] = $e1[1].clone();
1329 $out[4] = $e1[2].clone();
1330 $out[5] = $e1[3].clone();
1331 $out[7] = $e1[4].clone();
1332 $out[8] = $e1[5].clone();
1333 };
1334}
1335#[cfg(all(feature = "row_vector3", feature = "matrix2x3", feature = "matrix3"))]
1336vertcat_two_args!(VerticalConcatenateR3M2x3, RowVector3, Matrix2x3, Matrix3, vertcat_r3m2x3);
1337
1338macro_rules! vertcat_mdr4 {
1341 ($out:expr, $e0:expr, $e1:expr) => {
1342 let e0_len = $e0.len();
1343 for i in 0..e0_len {
1344 $out[i] = $e0[i].clone();
1345 }
1346 let offset = e0_len;
1347 $out[offset] = $e1[0].clone();
1348 $out[offset + 1] = $e1[1].clone();
1349 $out[offset + 2] = $e1[2].clone();
1350 $out[offset + 3] = $e1[3].clone();
1351 };
1352}
1353#[cfg(all(feature = "matrixd", feature = "row_vector4", feature = "matrix4"))]
1354vertcat_two_args!(VerticalConcatenateMDR4, DMatrix, RowVector4, Matrix4, vertcat_mdr4);
1355
1356macro_rules! vertcat_mdmd {
1359 ($out:expr, $e0:expr, $e1:expr) => {
1360 let dest_rows = $out.nrows();
1361 let mut offset = 0;
1362 let mut dest_ix = 0;
1363
1364 let src_rows = $e0.nrows();
1365 let stride = dest_rows - src_rows;
1366 dest_ix = offset;
1367 for ix in 0..$e0.len() {
1368 $out[dest_ix] = $e0[ix].clone();
1369 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1370 }
1371 offset += src_rows;
1372
1373 let src_rows = $e1.nrows();
1374 let stride = dest_rows - src_rows;
1375 dest_ix = offset;
1376 for ix in 0..$e1.len() {
1377 $out[dest_ix] = $e1[ix].clone();
1378 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1379 }
1380 };
1381}
1382#[cfg(all(feature = "matrixd", feature = "matrix4"))]
1383vertcat_two_args!(VerticalConcatenateMDMD, DMatrix, DMatrix, Matrix4, vertcat_mdmd);
1384
1385#[cfg(all(feature = "matrixd", feature = "matrix4", feature = "row_vector4"))]
1388vertcat_two_args!(VerticalConcatenateR4MD, RowVector4, DMatrix, Matrix4, vertcat_mdmd);
1389
1390macro_rules! vertcat_mdmdmd {
1393 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
1394 let dest_rows = $out.nrows();
1395 let mut offset = 0;
1396 let mut dest_ix = 0;
1397
1398 let src_rows = $e0.nrows();
1399 let stride = dest_rows - src_rows;
1400 dest_ix = offset;
1401 for ix in 0..$e0.len() {
1402 $out[dest_ix] = $e0[ix].clone();
1403 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1404 }
1405 offset += src_rows;
1406
1407 let src_rows = $e1.nrows();
1408 let stride = dest_rows - src_rows;
1409 dest_ix = offset;
1410 for ix in 0..$e1.len() {
1411 $out[dest_ix] = $e1[ix].clone();
1412 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1413 }
1414 offset += src_rows;
1415
1416 let src_rows = $e2.nrows();
1417 let stride = dest_rows - src_rows;
1418 dest_ix = offset;
1419 for ix in 0..$e2.len() {
1420 $out[dest_ix] = $e2[ix].clone();
1421 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1422 }
1423 };
1424}
1425
1426#[cfg(all(feature = "row_vector2", feature = "matrix3x2"))]
1427vertcat_three_args!(VerticalConcatenateR2R2R2, RowVector2, RowVector2, RowVector2, Matrix3x2, vertcat_mdmdmd);
1428
1429#[cfg(all(feature = "row_vector3", feature = "matrix3"))]
1432vertcat_three_args!(VerticalConcatenateR3R3R3, RowVector3, RowVector3, RowVector3, Matrix3, vertcat_mdmdmd);
1433
1434#[cfg(all(feature = "row_vector4", feature = "matrixd", feature = "matrix4"))]
1437vertcat_three_args!(VerticalConcatenateR4R4MD, RowVector4, RowVector4, DMatrix, Matrix4, vertcat_mdmdmd);
1438
1439#[cfg(all(feature = "row_vector4", feature = "matrixd", feature = "row_vector4", feature = "matrix4"))]
1442vertcat_three_args!(VerticalConcatenateR4MDR4, RowVector4, DMatrix, RowVector4, Matrix4, vertcat_mdmdmd);
1443
1444#[cfg(all(feature = "matrixd", feature = "row_vector4", feature = "row_vector4", feature = "matrix4"))]
1447vertcat_three_args!(VerticalConcatenateMDR4R4, DMatrix, RowVector4, RowVector4, Matrix4, vertcat_mdmdmd);
1448
1449macro_rules! vertcat_mdmdmdmd {
1452 ($out:expr, $e0:expr, $e1:expr, $e2:expr, $e3:expr) => {
1453 let dest_rows = $out.nrows();
1454 let mut offset = 0;
1455 let mut dest_ix = 0;
1456
1457 let src_rows = $e0.nrows();
1458 let stride = dest_rows - src_rows;
1459 dest_ix = offset;
1460 for ix in 0..$e0.len() {
1461 $out[dest_ix] = $e0[ix].clone();
1462 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1463 }
1464 offset += src_rows;
1465
1466 let src_rows = $e1.nrows();
1467 let stride = dest_rows - src_rows;
1468 dest_ix = offset;
1469 for ix in 0..$e1.len() {
1470 $out[dest_ix] = $e1[ix].clone();
1471 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1472 }
1473 offset += src_rows;
1474
1475 let src_rows = $e2.nrows();
1476 let stride = dest_rows - src_rows;
1477 dest_ix = offset;
1478 for ix in 0..$e2.len() {
1479 $out[dest_ix] = $e2[ix].clone();
1480 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1481 }
1482 offset += src_rows;
1483
1484 let src_rows = $e3.nrows();
1485 let stride = dest_rows - src_rows;
1486 dest_ix = offset;
1487 for ix in 0..$e3.len() {
1488 $out[dest_ix] = $e3[ix].clone();
1489 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
1490 }
1491 };
1492}
1493
1494#[cfg(all(feature = "matrix4", feature = "row_vector4"))]
1495vertcat_four_args!(VerticalConcatenateR4R4R4R4, RowVector4, RowVector4, RowVector4, RowVector4, Matrix4, vertcat_mdmdmdmd);
1496
1497macro_rules! impl_vertcat_arms {
1498 ($kind:ident, $args:expr, $default:expr) => {
1499 paste!{
1500 {
1501 let arguments = $args;
1502 let rows = arguments[0].shape()[0];
1503 let rows:usize = arguments.iter().fold(0, |acc, x| acc + x.shape()[0]);
1504 let columns:usize = arguments[0].shape()[1];
1505 let nargs = arguments.len();
1506 let kinds: Vec<ValueKind> = arguments.iter().map(|x| x.kind()).collect::<Vec<ValueKind>>();
1507 let no_refs = !kinds.iter().any(|x| {
1508 match x {
1509 ValueKind::Reference(_) => true,
1510 ValueKind::Matrix(_,_) => true,
1511 _ => false,
1512 }});
1513 if no_refs {
1514 let mat: Vec<$kind> = arguments.iter().flat_map(|v| v.[<as_vec $kind:lower>]().unwrap()).collect::<Vec<$kind>>();
1515 fn to_column_major<T: Clone>(out: &[Value], row_n: usize, col_n: usize, extract_fn: impl Fn(&Value) -> MResult<Vec<T>> + Clone) -> Vec<T> {
1516 (0..col_n).flat_map(|col| out.iter().map({let value = extract_fn.clone();move |row| value(row).unwrap()[col].clone()})).collect()
1517 }
1518 let mat = to_column_major(&arguments, rows, columns, |v| v.[<as_vec $kind:lower>]());
1519 match (rows,columns) {
1520 #[cfg(feature = "matrix1")]
1521 (1,1) => {return Ok(Box::new(VerticalConcatenateS1{out:Ref::new(Matrix1::from_vec(mat))}));}
1522 #[cfg(feature = "vector2")]
1523 (2,1) => {return Ok(Box::new(VerticalConcatenateS2{out:Ref::new(Vector2::from_vec(mat))}));}
1524 #[cfg(feature = "vector3")]
1525 (3,1) => {return Ok(Box::new(VerticalConcatenateS3{out:Ref::new(Vector3::from_vec(mat))}));}
1526 #[cfg(feature = "vector4")]
1527 (4,1) => {return Ok(Box::new(VerticalConcatenateS4{out:Ref::new(Vector4::from_vec(mat))}));}
1528 #[cfg(feature = "vectord")]
1529 (m,1) => {return Ok(Box::new(VerticalConcatenateSD{out:Ref::new(DVector::from_vec(mat))}));}
1530 #[cfg(feature = "matrix2")]
1531 (2,2) => {return Ok(Box::new(VerticalConcatenateM2{out:Ref::new(Matrix2::from_vec(mat))}));}
1532 #[cfg(feature = "matrix3")]
1533 (3,3) => {return Ok(Box::new(VerticalConcatenateM3{out:Ref::new(Matrix3::from_vec(mat))}));}
1534 #[cfg(feature = "matrix4")]
1535 (4,4) => {return Ok(Box::new(VerticalConcatenateM4{out:Ref::new(Matrix4::from_vec(mat))}));}
1536 #[cfg(feature = "matrix2x3")]
1537 (2,3) => {return Ok(Box::new(VerticalConcatenateM2x3{out:Ref::new(Matrix2x3::from_vec(mat))}));}
1538 #[cfg(feature = "matrix3x2")]
1539 (3,2) => {return Ok(Box::new(VerticalConcatenateM3x2{out:Ref::new(Matrix3x2::from_vec(mat))}));}
1540 #[cfg(feature = "matrixd")]
1541 (m,n) => {return Ok(Box::new(VerticalConcatenateMD{out:Ref::new(DMatrix::from_vec(m,n,mat))}));}
1542 _ => Err(MechError2::new(
1543 FeatureNotEnabledError,
1544 None
1545 ).with_compiler_loc()),
1546 }
1547 } else {
1548 match (nargs,rows,columns) {
1549 #[cfg(feature = "vector2")]
1550 (1,2,1) => {
1551 match &arguments[..] {
1552 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0))] => {
1554 return Ok(Box::new(VerticalConcatenateV2{out: e0.clone()}));
1555 }
1556 _ => todo!(),
1557 }
1558 }
1559 #[cfg(feature = "vector3")]
1560 (1,3,1) => {
1561 match &arguments[..] {
1562 [Value::MutableReference(e0)] => {
1564 match *e0.borrow() {
1565 Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e0)) => {
1566 return Ok(Box::new(VerticalConcatenateV3{out: e0.clone()}));
1567 }
1568 _ => todo!(),
1569 }
1570 }
1571 _ => todo!(),
1572 }
1573 }
1574 #[cfg(feature = "vector4")]
1575 (1,4,1) => {
1576 match &arguments[..] {
1577 [Value::[<Matrix $kind:camel>](Matrix::Vector4(ref e0))] => {
1579 return Ok(Box::new(VerticalConcatenateV4{out: e0.clone()}));
1580 }
1581 _ => todo!(),
1582 }
1583 }
1584 #[cfg(feature = "vectord")]
1585 (1,m,1) => {
1586 match &arguments[..] {
1587 [Value::[<Matrix $kind:camel>](Matrix::DVector(ref e0))] => {
1589 return Ok(Box::new(VerticalConcatenateVD{out: e0.clone()}));
1590 }
1591 _ => todo!(),
1592 }
1593 }
1594 #[cfg(all(feature = "matrix1", feature = "vector2"))]
1595 (2,2,1) => {
1596 let mut out = Vector2::from_element($default);
1597 match &arguments[..] {
1598 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
1600 return Ok(Box::new(VerticalConcatenateM1M1{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1601 }
1602 _ => todo!(),
1603 }
1604 }
1605 #[cfg(all(feature = "matrix1", feature = "vector3", feature = "vector2"))]
1606 (2,3,1) => {
1607 let mut out = Vector3::from_element($default);
1608 match &arguments[..] {
1609 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1))] => {
1611 return Ok(Box::new(VerticalConcatenateM1V2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1612 }
1613 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
1615 return Ok(Box::new(VerticalConcatenateV2M1{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1616 }
1617 _ => todo!(),
1618 }
1619 }
1620 #[cfg(feature = "vector4")]
1621 (2,4,1) => {
1622 let mut out = Vector4::from_element($default);
1623 match &arguments[..] {
1624 #[cfg(all(feature = "matrix1", feature = "vector3"))]
1626 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e1))] => {
1627 return Ok(Box::new(VerticalConcatenateM1V3{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1628 }
1629 #[cfg(all(feature = "matrix1", feature = "vector3"))]
1631 [Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
1632 return Ok(Box::new(VerticalConcatenateV3M1{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1633 }
1634 #[cfg(feature = "vector2")]
1636 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1))] => {
1637 return Ok(Box::new(VerticalConcatenateV2V2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1638 }
1639 _ => todo!(),
1640 }
1641 }
1642 #[cfg(feature = "vectord")]
1643 (2,m,1) => {
1644 let mut out = DVector::from_element(m,$default);
1645 match &arguments[..] {
1646 [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1)] => {
1647 let e0 = e0.get_copyable_matrix();
1648 let e1 = e1.get_copyable_matrix();
1649 return Ok(Box::new(VerticalConcatenateVD2{e0, e1, out: Ref::new(out)}));
1650 }
1651 _ => todo!(),
1652 }
1653 }
1654 #[cfg(feature = "vector3")]
1655 (3,3,1) => {
1656 let mut out = Vector3::from_element($default);
1657 match &arguments[..] {
1658 #[cfg(feature = "matrix1")]
1660 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
1661 return Ok(Box::new(VerticalConcatenateM1M1M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
1662 }
1663 _ => todo!()
1664 }
1665 }
1666 #[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector4"))]
1667 (3,4,1) => {
1668 let mut out = Vector4::from_element($default);
1669 match &arguments[..] {
1670 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e2))] => {
1672 return Ok(Box::new(VerticalConcatenateM1M1V2{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
1673 }
1674 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
1676 return Ok(Box::new(VerticalConcatenateM1V2M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
1677 }
1678 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
1680 return Ok(Box::new(VerticalConcatenateV2M1M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
1681 }
1682 _ => todo!()
1683 }
1684 }
1685 #[cfg(feature = "vectord")]
1686 (3,m,1) => {
1687 let mut out = DVector::from_element(m,$default);
1688 match &arguments[..] {
1689 [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1),Value::[<Matrix $kind:camel>](e2)] => {
1690 let e0 = e0.get_copyable_matrix();
1691 let e1 = e1.get_copyable_matrix();
1692 let e2 = e2.get_copyable_matrix();
1693 return Ok(Box::new(VerticalConcatenateVD3{e0, e1, e2, out: Ref::new(out)}));
1694 }
1695 _ => todo!(),
1696 }
1697 }
1698 #[cfg(all(feature = "matrix1", feature = "vector4"))]
1699 (4,4,1) => {
1700 let mut out = Vector4::from_element($default);
1701 match &arguments[..] {
1702 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e3))] => {
1704 return Ok(Box::new(VerticalConcatenateM1M1M1M1{ e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), e3: e3.clone(), out: Ref::new(out) }));
1705 }
1706 _ => todo!(),
1707 }
1708 }
1709 #[cfg(feature = "vectord")]
1710 (4,m,1) => {
1711 let mut out = DVector::from_element(m,$default);
1712 match &arguments[..] {
1713 [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1),Value::[<Matrix $kind:camel>](e2),Value::[<Matrix $kind:camel>](e3)] => {
1714 let e0 = e0.get_copyable_matrix();
1715 let e1 = e1.get_copyable_matrix();
1716 let e2 = e2.get_copyable_matrix();
1717 let e3 = e3.get_copyable_matrix();
1718 return Ok(Box::new(VerticalConcatenateVD4{e0, e1, e2, e3, out: Ref::new(out)}));
1719 }
1720 _ => todo!(),
1721 }
1722 }
1723 #[cfg(feature = "vectord")]
1724 (l,m,1) => {
1725 let mut out = DVector::from_element(m,$default);
1726 let mut matrix_args: Vec<(Box<dyn CopyMat<$kind>>,usize)> = vec![];
1727 let mut scalar_args: Vec<(Ref<$kind>,usize)> = vec![];
1728 let mut i = 0;
1729 for arg in arguments.iter() {
1730 match &arg {
1731 Value::[<$kind:camel>](e0) => {
1732 scalar_args.push((e0.clone(),i));
1733 i += 1;
1734 }
1735 Value::[<Matrix $kind:camel>](e0) => {
1736 matrix_args.push((e0.get_copyable_matrix(),i));
1737 i += e0.shape()[0];
1738 }
1739 _ => todo!(),
1740 }
1741 }
1742 return Ok(Box::new(VerticalConcatenateVDN{scalar: scalar_args, matrix: matrix_args, out: Ref::new(out)}));
1743 }
1744 #[cfg(feature = "matrix2")]
1745 (2,2,2) => {
1746 let mut out = Matrix2::from_element($default);
1747 match &arguments[..] {
1748 #[cfg(feature = "row_vector2")]
1750 [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1))] => {return Ok(Box::new(VerticalConcatenateR2R2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));}
1751 _ => todo!(),
1752 }
1753 }
1754 #[cfg(feature = "matrix2x3")]
1755 (2,2,3) => {
1756 let mut out = Matrix2x3::from_element($default);
1757 match &arguments[..] {
1758 #[cfg(feature = "row_vector3")]
1760 [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1))] => {return Ok(Box::new(VerticalConcatenateR3R3{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));}
1761 _ => todo!(),
1762 }
1763 }
1764 #[cfg(feature = "matrix3x2")]
1765 (2,3,2) => {
1766 let mut out = Matrix3x2::from_element($default);
1767 match &arguments[..] {
1768 #[cfg(all(feature = "row_vector2", feature = "matrix2"))]
1770 [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix2(ref e1))] => {
1771 return Ok(Box::new(VerticalConcatenateR2M2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1772 }
1773 #[cfg(all(feature = "matrix2", feature = "row_vector2"))]
1775 [Value::[<Matrix $kind:camel>](Matrix::Matrix2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1))] => {
1776 return Ok(Box::new(VerticalConcatenateM2R2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1777 }
1778 _ => todo!(),
1779 }
1780
1781 }
1782 #[cfg(feature = "matrix3")]
1783 (2,3,3) => {
1784 let mut out = Matrix3::from_element($default);
1785 match &arguments[..] {
1786 #[cfg(all(feature = "row_vector3", feature = "matrix2x3"))]
1788 [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix2x3(ref e1))] => {
1789 return Ok(Box::new(VerticalConcatenateR3M2x3 { e0: e0.clone(), e1: e1.clone(), out: Ref::new(out) }));
1790 }
1791 #[cfg(all(feature = "matrix2x3", feature = "row_vector3"))]
1793 [Value::[<Matrix $kind:camel>](Matrix::Matrix2x3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1))] => {
1794 return Ok(Box::new(VerticalConcatenateM2x3R3 { e0: e0.clone(), e1: e1.clone(), out: Ref::new(out) }));
1795 }
1796 _ => todo!(),
1797 }
1798
1799 }
1800 #[cfg(feature = "matrix4")]
1801 (2,4,4) => {
1802 let mut out = Matrix4::from_element($default);
1803 match &arguments[..] {
1804 #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1806 [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)), Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e1))] => Ok(Box::new(VerticalConcatenateR4MD{e0:e0.clone(),e1:e1.clone(),out:Ref::new(out)})),
1807 #[cfg(all(feature = "matrixd", feature = "row_vector4"))]
1809 [Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1))] => Ok(Box::new(VerticalConcatenateMDR4{e0:e0.clone(),e1:e1.clone(),out:Ref::new(out)})),
1810 #[cfg(feature = "matrixd")]
1812 [Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e0)), Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e1))] => Ok(Box::new(VerticalConcatenateMDMD{e0:e0.clone(),e1:e1.clone(),out:Ref::new(out)})),
1813 _ => todo!(),
1814 }
1815
1816 }
1817 #[cfg(feature = "matrixd")]
1818 (2,m,n) => {
1819 let mut out = DMatrix::from_element(m,n,$default);
1820 match &arguments[..] {
1821 [Value::[<Matrix $kind:camel>](m0), Value::[<Matrix $kind:camel>](m1)] => {
1822 let e0 = m0.get_copyable_matrix();
1823 let e1 = m1.get_copyable_matrix();
1824 Ok(Box::new(VerticalConcatenateTwoArgs{e0, e1, out: Ref::new(out)}))
1825 }
1826 _ => todo!(),
1827 }
1828 }
1829 #[cfg(feature = "matrix3x2")]
1830 (3,3,2) => {
1831 let mut out = Matrix3x2::from_element($default);
1832 match &arguments[..] {
1833 #[cfg(feature = "row_vector2")]
1835 [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e2))]=>Ok(Box::new(VerticalConcatenateR2R2R2{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1836 _ => todo!(),
1837 }
1838 }
1839 #[cfg(feature = "matrix3")]
1840 (3,3,3) => {
1841 let mut out = Matrix3::from_element($default);
1842 match &arguments[..] {
1843 #[cfg(feature = "row_vector3")]
1845 [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e2))]=>Ok(Box::new(VerticalConcatenateR3R3R3{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1846 _ => todo!(),
1847 }
1848 }
1849 #[cfg(feature = "matrix4")]
1850 (3,4,4) => {
1851 let mut out = Matrix4::from_element($default);
1852 match &arguments[..] {
1853 #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1855 [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1)),Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e2))]=>Ok(Box::new(VerticalConcatenateR4R4MD{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1856 #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1858 [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)),Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e2))]=>Ok(Box::new(VerticalConcatenateR4MDR4{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1859 #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1861 [Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e2))]=>Ok(Box::new(VerticalConcatenateMDR4R4{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1862 _ => todo!(),
1863 }
1864 }
1865 #[cfg(feature = "matrixd")]
1866 (3,m,n) => {
1867 let mut out = DMatrix::from_element(m,n,$default);
1868 match &arguments[..] {
1869 [Value::[<Matrix $kind:camel>](m0),Value::[<Matrix $kind:camel>](m1),Value::[<Matrix $kind:camel>](m2)] => {
1870 let e0 = m0.get_copyable_matrix();
1871 let e1 = m1.get_copyable_matrix();
1872 let e2 = m2.get_copyable_matrix();
1873 Ok(Box::new(VerticalConcatenateThreeArgs{e0,e1,e2,out:Ref::new(out)}))
1874 }
1875 _ => todo!(),
1876 }
1877 }
1878 #[cfg(feature = "matrix4")]
1879 (4,4,4) => {
1880 let mut out = Matrix4::from_element($default);
1881 match &arguments[..] {
1882 #[cfg(feature = "row_vector4")]
1884 [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e2)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e3))]=>Ok(Box::new(VerticalConcatenateR4R4R4R4{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),e3:e3.clone(),out:Ref::new(out)})),
1885 _ => todo!(),
1886 }
1887 }
1888 #[cfg(feature = "matrixd")]
1889 (4,m,n) => {
1890 let mut out = DMatrix::from_element(m,n,$default);
1891 match &arguments[..] {
1892 [Value::[<Matrix $kind:camel>](m0),Value::[<Matrix $kind:camel>](m1),Value::[<Matrix $kind:camel>](m2),Value::[<Matrix $kind:camel>](m3)] => {
1893 let e0 = m0.get_copyable_matrix();
1894 let e1 = m1.get_copyable_matrix();
1895 let e2 = m2.get_copyable_matrix();
1896 let e3 = m3.get_copyable_matrix();
1897 Ok(Box::new(VerticalConcatenateFourArgs{e0,e1,e2,e3,out:Ref::new(out)}))
1898 }
1899 _ => todo!(),
1900 }
1901 }
1902 #[cfg(feature = "matrixd")]
1903 (l,m,n) => {
1904 let mut out = DMatrix::from_element(m,n,$default);
1905 let mut args = vec![];
1906 for arg in arguments {
1907 match arg {
1908 Value::[<Matrix $kind:camel>](m0) => {
1909 let e0 = m0.get_copyable_matrix();
1910 args.push(e0);
1911 }
1912 _ => todo!(),
1913 }
1914 }
1915 Ok(Box::new(VerticalConcatenateNArgs{e0: args, out:Ref::new(out)}))
1916 }
1917 _ => {return Err(MechError2::new(
1918 UnhandledFunctionArgumentKindVarg { arg: arguments.iter().map(|x| x.kind()).collect(), fxn_name: "matrix/vertcat".to_string() },
1919 None
1920 ).with_compiler_loc()
1921 );
1922 }
1923 }
1924 }}}}}
1925
1926fn impl_vertcat_fxn(arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1927
1928 let kinds: Vec<ValueKind> = arguments.iter().map(|x| x.kind()).collect::<Vec<ValueKind>>();
1929 let target_kind = kinds[0].clone();
1930
1931 #[cfg(feature = "f64")]
1932 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::F64) { return impl_vertcat_arms!(f64, arguments, f64::default()) } }
1933
1934 #[cfg(feature = "f32")]
1935 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::F32) { return impl_vertcat_arms!(f32, arguments, f32::default()) } }
1936
1937 #[cfg(feature = "u8")]
1938 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U8) { return impl_vertcat_arms!(u8, arguments, u8::default()) } }
1939
1940 #[cfg(feature = "u16")]
1941 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U16) { return impl_vertcat_arms!(u16, arguments, u16::default()) } }
1942
1943 #[cfg(feature = "u32")]
1944 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U32) { return impl_vertcat_arms!(u32, arguments, u32::default()) } }
1945
1946 #[cfg(feature = "u64")]
1947 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U64) { return impl_vertcat_arms!(u64, arguments, u64::default()) } }
1948
1949 #[cfg(feature = "u128")]
1950 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U128){ return impl_vertcat_arms!(u128, arguments, u128::default()) } }
1951
1952 #[cfg(feature = "bool")]
1953 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::Bool) { return impl_vertcat_arms!(bool, arguments, bool::default()) } }
1954
1955 #[cfg(feature = "string")]
1956 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::String) { return impl_vertcat_arms!(String, arguments, String::default()) } }
1957
1958 #[cfg(feature = "rational")]
1959 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::R64) { return impl_vertcat_arms!(R64, arguments, R64::default()) } }
1960
1961 #[cfg(feature = "complex")]
1962 { if ValueKind::is_compatible(target_kind.clone(), ValueKind::C64) { return impl_vertcat_arms!(C64, arguments, C64::default()) } }
1963
1964 Err(MechError2::new(
1965 UnhandledFunctionArgumentKindVarg { arg: arguments.iter().map(|x| x.kind()).collect(), fxn_name: "matrix/vertcat".to_string() },
1966 None
1967 ).with_compiler_loc()
1968 )
1969}
1970
1971
1972pub struct MatrixVertCat {}
1973impl NativeFunctionCompiler for MatrixVertCat {
1974 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1975 impl_vertcat_fxn(arguments)
1976 }
1977}
1978
1979register_descriptor! {
1980 FunctionCompilerDescriptor {
1981 name: "matrix/vertcat",
1982 ptr: &MatrixVertCat{},
1983 }
1984}
1985
1986#[derive(Debug, Clone)]
1987pub struct VerticalConcatenateDimensionMismatch {
1988 pub rows: usize,
1989 pub cols: usize,
1990}
1991impl MechErrorKind2 for VerticalConcatenateDimensionMismatch {
1992 fn name(&self) -> &str { "VerticalConcatenateDimensionMismatch" }
1993 fn message(&self) -> String {
1994 format!("Cannot vertically concatenate matrices/vectors with dimensions ({}, {})", self.rows, self.cols)
1995 }
1996}