mech_math/ops/
modulus.rs

1#[macro_use]
2use crate::*;
3use num_traits::*;
4#[cfg(feature = "matrix")]
5use mech_core::matrix::Matrix;
6
7// Mod ------------------------------------------------------------------------
8
9#[macro_export]
10macro_rules! impl_binop2 {
11  ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident, $feature_flag:expr) => {
12    #[derive(Debug)]
13    struct $struct_name<T> {
14      lhs: Ref<$arg1_type>,
15      rhs: Ref<$arg2_type>,
16      out: Ref<$out_type>,
17    }
18    impl<T> MechFunctionFactory for $struct_name<T>
19    where
20      T: Copy + Debug + Clone + Sync + Send + 'static + 
21      PartialEq + PartialOrd + CompileConst + ConstElem +
22      Add<Output = T> + AddAssign +
23      Sub<Output = T> + SubAssign +
24      Mul<Output = T> + MulAssign +
25      Div<Output = T> + DivAssign +
26      Rem<Output = T> + RemAssign +
27      Zero + One + AsValueKind,
28      Ref<$out_type>: ToValue
29    {
30      fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
31        match args {
32          FunctionArgs::Binary(out, arg1, arg2) => {
33            let lhs: Ref<$arg1_type> = unsafe { arg1.as_unchecked() }.clone();
34            let rhs: Ref<$arg2_type> = unsafe { arg2.as_unchecked() }.clone();
35            let out: Ref<$out_type> = unsafe { out.as_unchecked() }.clone();
36            Ok(Box::new(Self {lhs, rhs, out }))
37          },
38          _ => Err(MechError2::new(
39              IncorrectNumberOfArguments { expected: 2, found: 0 },
40              None
41            ).with_compiler_loc()
42          ),
43        }
44      }
45    }
46    impl<T> MechFunctionImpl for $struct_name<T>
47    where
48      T: Copy + Debug + Clone + Sync + Send + 'static + 
49      PartialEq + PartialOrd +
50      Add<Output = T> + AddAssign +
51      Sub<Output = T> + SubAssign +
52      Mul<Output = T> + MulAssign +
53      Div<Output = T> + DivAssign +
54      Rem<Output = T> + RemAssign +
55      Zero + One,
56      Ref<$out_type>: ToValue
57    {
58    fn solve(&self) {
59      let lhs_ptr = self.lhs.as_ptr();
60      let rhs_ptr = self.rhs.as_ptr();
61      let out_ptr = self.out.as_mut_ptr();
62      $op!(lhs_ptr,rhs_ptr,out_ptr);
63    }
64    fn out(&self) -> Value { self.out.to_value() }
65    fn to_string(&self) -> String { format!("{:#?}", self) }
66  }
67  #[cfg(feature = "compiler")]
68  impl<T> MechFunctionCompiler for $struct_name<T> 
69  where
70    T: CompileConst + ConstElem + AsValueKind
71  {
72    fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
73      let name = format!("{}<{}>", stringify!($struct_name), T::as_value_kind());
74      compile_binop!(name, self.out, self.lhs, self.rhs, ctx, $feature_flag);
75    }
76  }};
77}
78
79macro_rules! mod_op {
80    ($lhs:expr, $rhs:expr, $out:expr) => {
81      unsafe { *$out = *$lhs % *$rhs; }};}
82  
83macro_rules! mod_vec_op {
84  ($lhs:expr, $rhs:expr, $out:expr) => {
85    unsafe {
86      let mut out_deref = &mut (*$out);
87      let lhs_deref = &(*$lhs);
88      let rhs_deref = &(*$rhs);
89      for (o,(l,r)) in out_deref.iter_mut().zip(lhs_deref.iter().zip(rhs_deref.iter())) {
90        *o = *l % *r;
91      }
92    }};}
93
94macro_rules! mod_scalar_lhs_op {
95  ($lhs:expr, $rhs:expr, $out:expr) => {
96    unsafe { 
97      let mut out_deref = &mut (*$out);
98      let lhs_deref = &(*$lhs);
99      let rhs_deref = (*$rhs);
100      for (o,l) in out_deref.iter_mut().zip(lhs_deref.iter()) {
101        *o = *l % rhs_deref;
102      }
103    }};}
104
105macro_rules! mod_scalar_rhs_op {
106  ($lhs:expr, $rhs:expr, $out:expr) => {
107    unsafe {
108      let mut out_deref = &mut (*$out);
109      let lhs_deref = (*$lhs);
110      let rhs_deref = &(*$rhs);
111      for (o,r) in out_deref.iter_mut().zip(rhs_deref.iter()) {
112        *o = lhs_deref % *r;
113      }
114    }};}
115
116macro_rules! mod_mat_vec_op {
117  ($lhs:expr, $rhs:expr, $out:expr) => {
118    unsafe {
119      let mut out_deref = &mut (*$out);
120      let lhs_deref = &(*$lhs);
121      let rhs_deref = &(*$rhs);
122      for (mut col, lhs_col) in out_deref.column_iter_mut().zip(lhs_deref.column_iter()) {
123        for i in 0..col.len() {
124          col[i] = lhs_col[i] % rhs_deref[i];
125        }
126      }
127    }
128  };}
129
130macro_rules! mod_vec_mat_op {
131  ($lhs:expr, $rhs:expr, $out:expr) => {
132    unsafe {
133      let mut out_deref = &mut (*$out);
134      let lhs_deref = &(*$lhs);
135      let rhs_deref = &(*$rhs);
136      for (mut col, rhs_col) in out_deref.column_iter_mut().zip(rhs_deref.column_iter()) {
137        for i in 0..col.len() {
138          col[i] = lhs_deref[i] % rhs_col[i];
139        }
140      }
141    }
142  };}
143
144macro_rules! mod_mat_row_op {
145  ($lhs:expr, $rhs:expr, $out:expr) => {
146    unsafe {
147      let mut out_deref = &mut (*$out);
148      let lhs_deref = &(*$lhs);
149      let rhs_deref = &(*$rhs);
150      for (mut row, lhs_row) in out_deref.row_iter_mut().zip(lhs_deref.row_iter()) {
151        for i in 0..row.len() {
152          row[i] = lhs_row[i] % rhs_deref[i];
153        }
154      }
155    }
156  };}
157
158macro_rules! mod_row_mat_op {
159  ($lhs:expr, $rhs:expr, $out:expr) => {
160    unsafe {
161      let mut out_deref = &mut (*$out);
162      let lhs_deref = &(*$lhs);
163      let rhs_deref = &(*$rhs);
164      for (mut row, rhs_row) in out_deref.row_iter_mut().zip(rhs_deref.row_iter()) {
165        for i in 0..row.len() {
166          row[i] = lhs_deref[i] % rhs_row[i];
167        }
168      }
169    }
170  };}  
171
172
173macro_rules! impl_math_fxns2 {
174  ($lib:ident) => {
175    impl_fxns!($lib,T,T,impl_binop2);
176  }}
177
178impl_math_fxns2!(Mod);
179
180fn impl_mod_fxn(lhs_value: Value, rhs_value: Value) -> MResult<Box<dyn MechFunction>> {
181  impl_binop_match_arms!(
182    Mod,
183    register_fxn_descriptor_inner,
184    (lhs_value, rhs_value),
185    I8,   i8,   "i8";
186    I16,  i16,  "i16";
187    I32,  i32,  "i32";
188    I64,  i64,  "i64";
189    I128, i128, "i128";
190    U8,   u8,   "u8";
191    U16,  u16,  "u16";
192    U32,  u32,  "u32";
193    U64,  u64,  "u64";
194    U128, u128, "u128";
195    F32,  f32,  "f32";
196    F64,  f64,  "f64";
197  )
198}
199
200impl_mech_binop_fxn!(MathMod,impl_mod_fxn,"math/mod");