1
2use crate::*;
3use num_traits::*;
4
5#[cfg(feature = "matrix")]
6use mech_core::matrix::Matrix;
7
8macro_rules! add_op {
11($lhs:expr, $rhs:expr, $out:expr) => {
12 unsafe { *$out = *$lhs + *$rhs; }
13 };}
14
15macro_rules! add_vec_op {
16 ($lhs:expr, $rhs:expr, $out:expr) => {
17 unsafe { (*$lhs).add_to(&*$rhs,&mut *$out) }
18 };}
19
20macro_rules! add_mat_vec_op {
21 ($lhs:expr, $rhs:expr, $out:expr) => {
22 unsafe {
23 let mut out_deref = &mut (*$out);
24 let lhs_deref = &(*$lhs);
25 let rhs_deref = &(*$rhs);
26 for (mut col, lhs_col) in out_deref.column_iter_mut().zip(lhs_deref.column_iter()) {
27 lhs_col.add_to(&rhs_deref,&mut col);
28 }
29 }
30 };}
31
32macro_rules! add_vec_mat_op {
33 ($lhs:expr, $rhs:expr, $out:expr) => {
34 unsafe {
35 let mut out_deref = &mut (*$out);
36 let lhs_deref = &(*$lhs);
37 let rhs_deref = &(*$rhs);
38 for (mut col, rhs_col) in out_deref.column_iter_mut().zip(rhs_deref.column_iter()) {
39 lhs_deref.add_to(&rhs_col,&mut col);
40 }
41 }
42 };}
43
44macro_rules! add_mat_row_op {
45 ($lhs:expr, $rhs:expr, $out:expr) => {
46 unsafe {
47 let mut out_deref = &mut (*$out);
48 let lhs_deref = &(*$lhs);
49 let rhs_deref = &(*$rhs);
50 for (mut row, lhs_row) in out_deref.row_iter_mut().zip(lhs_deref.row_iter()) {
51 lhs_row.add_to(&rhs_deref,&mut row);
52 }
53 }
54 };}
55
56macro_rules! add_row_mat_op {
57 ($lhs:expr, $rhs:expr, $out:expr) => {
58 unsafe {
59 let mut out_deref = &mut (*$out);
60 let lhs_deref = &(*$lhs);
61 let rhs_deref = &(*$rhs);
62 for (mut row, rhs_row) in out_deref.row_iter_mut().zip(rhs_deref.row_iter()) {
63 lhs_deref.add_to(&rhs_row,&mut row);
64 }
65 }
66 };}
67
68macro_rules! add_scalar_lhs_op {
69 ($lhs:expr, $rhs:expr, $out:expr) => {
70 unsafe { *$out = (*$lhs).add_scalar(*$rhs); }
71 };}
72
73macro_rules! add_scalar_rhs_op {
74 ($lhs:expr, $rhs:expr, $out:expr) => {
75 unsafe { *$out = (*$rhs).add_scalar(*$lhs); }
76 };}
77
78impl_math_fxns!(Add);
79
80fn impl_add_fxn(lhs_value: Value, rhs_value: Value) -> MResult<Box<dyn MechFunction>> {
81 #[cfg(feature = "c64")]
82 match (&lhs_value, &rhs_value) {
83 (Value::C64(lhs), rhs) if !matches!(rhs, Value::C64(_)) => {
84 if let Ok(rhs_c64) = rhs.as_c64() {
85 return impl_add_fxn(Value::C64(lhs.clone()), Value::C64(rhs_c64));
86 }
87 }
88 (lhs, Value::C64(rhs)) if !matches!(lhs, Value::C64(_)) => {
89 if let Ok(lhs_c64) = lhs.as_c64() {
90 return impl_add_fxn(Value::C64(lhs_c64), Value::C64(rhs.clone()));
91 }
92 }
93 _ => {}
94 }
95
96 impl_binop_match_arms!(
97 Add,
98 register_fxn_descriptor_inner,
99 (lhs_value, rhs_value),
100 I8, i8, "i8";
101 I16, i16, "i16";
102 I32, i32, "i32";
103 I64, i64, "i64";
104 I128, i128, "i128";
105 U8, u8, "u8";
106 U16, u16, "u16";
107 U32, u32, "u32";
108 U64, u64, "u64";
109 U128, u128, "u128";
110 F32, f32, "f32";
111 F64, f64, "f64";
112 R64, R64, "rational";
113 C64, C64, "complex";
114 )
115}
116
117impl_mech_binop_fxn!(MathAdd,impl_add_fxn,"math/add");