1#[macro_use]
2use crate::*;
3
4use std::fmt::Debug;
5use std::marker::PhantomData;
6
7#[cfg(feature = "matrix")]
8use nalgebra::{
9 base::{Matrix as naMatrix, Storage, StorageMut},
10 Dim, Scalar,
11};
12
13#[cfg(feature = "add_assign")]
14pub mod add_assign;
15#[cfg(feature = "sub_assign")]
16pub mod sub_assign;
17#[cfg(feature = "div_assign")]
18pub mod div_assign;
19#[cfg(feature = "mul_assign")]
20pub mod mul_assign;
21
22#[cfg(feature = "add_assign")]
23pub use self::add_assign::*;
24#[cfg(feature = "sub_assign")]
25pub use self::sub_assign::*;
26#[cfg(feature = "div_assign")]
27pub use self::div_assign::*;
28#[cfg(feature = "mul_assign")]
29pub use self::mul_assign::*;
30
31#[macro_export]
32macro_rules! impl_op_assign_range_fxn_s {
33 ($struct_name:ident, $op:ident, $ix:ty) => {
34 #[derive(Debug)]
35 pub struct $struct_name<T, MatA, IxVec> {
36 pub source: Ref<T>,
37 pub ixes: Ref<IxVec>,
38 pub sink: Ref<MatA>,
39 pub _marker: PhantomData<T>,
40 }
41 impl<T, R1: 'static, C1: 'static, S1: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
42 where
43 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
44 T: Copy + Debug + Clone + Sync + Send + 'static +
45 Div<Output = T> + DivAssign +
46 Add<Output = T> + AddAssign +
47 Sub<Output = T> + SubAssign +
48 Mul<Output = T> + MulAssign +
49 Zero + One +
50 PartialEq + PartialOrd +
51 CompileConst + ConstElem + AsValueKind,
52 IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
53 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
54 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
55 {
56 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
57 match args {
58 FunctionArgs::Binary(out, arg1, arg2) => {
59 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
60 let ixes: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
61 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
62 Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
63 },
64 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{} requires 3 arguments, got {:?}", stringify!($struct_name), args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
65 }
66 }
67 }
68 impl<T, R1, C1, S1, IxVec> MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
69 where
70 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
71 T: Copy + Debug + Clone + Sync + Send + 'static +
72 Div<Output = T> + DivAssign +
73 Add<Output = T> + AddAssign +
74 Sub<Output = T> + SubAssign +
75 Mul<Output = T> + MulAssign +
76 Zero + One +
77 PartialEq + PartialOrd,
78 IxVec: AsRef<[$ix]> + Debug,
79 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
80 {
81 fn solve(&self) {
82 unsafe {
83 let sink_ptr = &mut *self.sink.as_mut_ptr();
84 let source_ptr = &*self.source.as_ptr();
85 let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
86 $op!(source_ptr,ix_ptr,sink_ptr);
87 }
88 }
89 fn out(&self) -> Value {self.sink.to_value()}
90 fn to_string(&self) -> String {format!("{:#?}", self)}
91 }
92 #[cfg(feature = "compiler")]
93 impl<T, R1, C1, S1, IxVec> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
94 where
95 T: CompileConst + ConstElem + AsValueKind,
96 IxVec: CompileConst + ConstElem + AsNaKind,
97 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
98 {
99 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
100 let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind(), IxVec::as_na_kind());
101 compile_binop!(name, self.sink, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::OpAssign));
102 }
103 }};}
104
105#[macro_export]
106macro_rules! impl_op_assign_range_fxn_v {
107 ($struct_name:ident, $op:ident, $ix:ty) => {
108 #[cfg(feature = "matrix")]
109 #[derive(Debug)]
110 pub struct $struct_name<T, MatA, MatB, IxVec> {
111 pub source: Ref<MatB>,
112 pub ixes: Ref<IxVec>,
113 pub sink: Ref<MatA>,
114 pub _marker: PhantomData<T>,
115 }
116 impl<T, R1: 'static, C1: 'static, S1: 'static, R2: 'static, C2: 'static, S2: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
117 where
118 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
119 Ref<naMatrix<T, R2, C2, S2>>: ToValue,
120 T: Copy + Debug + Clone + Sync + Send + 'static +
121 Div<Output = T> + DivAssign +
122 Add<Output = T> + AddAssign +
123 Sub<Output = T> + SubAssign +
124 Mul<Output = T> + MulAssign +
125 Zero + One +
126 PartialEq + PartialOrd +
127 CompileConst + ConstElem + AsValueKind,
128 IxVec: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix]>,
129 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
130 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
131 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
132 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
133 {
134 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
135 match args {
136 FunctionArgs::Binary(out, arg1, arg2) => {
137 let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
138 let ixes: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
139 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
140 Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
141 },
142 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{} requires 3 arguments, got {:?}", stringify!($struct_name), args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
143 }
144 }
145 }
146 impl<T, R1, C1, S1, R2, C2, S2, IxVec>
147 MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
148 where
149 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
150 T: Copy + Debug + Clone + Sync + Send + 'static +
151 Div<Output = T> + DivAssign +
152 Add<Output = T> + AddAssign +
153 Sub<Output = T> + SubAssign +
154 Mul<Output = T> + MulAssign +
155 Zero + One +
156 PartialEq + PartialOrd,
157 IxVec: AsRef<[$ix]> + Debug,
158 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
159 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
160 {
161 fn solve(&self) {
162 unsafe {
163 let sink_ptr = &mut *self.sink.as_mut_ptr();
164 let source_ptr = &*self.source.as_ptr();
165 let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
166 $op!(source_ptr,ix_ptr,sink_ptr);
167 }
168 }
169 fn out(&self) -> Value {self.sink.to_value()}
170 fn to_string(&self) -> String {format!("{:#?}", self)}
171 }
172 #[cfg(feature = "compiler")]
173 impl<T, R1, C1, S1, R2, C2, S2, IxVec> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
174 where
175 T: CompileConst + ConstElem + AsValueKind,
176 IxVec: CompileConst + ConstElem + AsNaKind,
177 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
178 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
179 {
180 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
181 let name = format!("{}<{}{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind(), naMatrix::<T, R2, C2, S2>::as_na_kind(), IxVec::as_na_kind());
182 compile_binop!(name, self.sink, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::OpAssign));
183 }
184 }
185 };}
186
187#[macro_export]
189macro_rules! op_assign_range_fxn {
190 ($op_fxn_name:tt, $fxn_name:ident) => {
191 paste::paste! {
192 fn $op_fxn_name(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
193 let arg = (sink, ixes.as_slice(), source);
194 impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, u8, "u8")
195 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, u16, "u16"))
196 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, u32, "u32"))
197 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, u64, "u64"))
198 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, u128, "u128"))
199 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, i8, "i8"))
200 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, i16, "i16"))
201 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, i32, "i32"))
202 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, i64, "i64"))
203 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, F32, "f32"))
204 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, F64, "f64"))
205 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, R64, "rational"))
206 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, $fxn_name, arg, C64, "complex"))
207 .map_err(|_| MechError { file: file!().to_string(), tokens: vec![], msg: format!("Unsupported argument: {:?}", &arg), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind})
208 }
209 }
210 }
211}
212
213#[macro_export]
214macro_rules! op_assign_range_all_fxn {
215 ($op_fxn_name:tt, $fxn_name:ident) => {
216 paste::paste! {
217 fn $op_fxn_name(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
218 let arg = (sink, ixes.as_slice(), source);
219 impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u8, "u8")
220 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u16, "u16"))
221 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u32, "u32"))
222 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u64, "u64"))
223 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u128, "u128"))
224 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i8, "i8"))
225 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i16, "i16"))
226 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i32, "i32"))
227 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i64, "i64"))
228 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, F32, "f32"))
229 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, F64, "f64"))
230 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, R64, "rational"))
231 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, C64, "complex"))
232 .map_err(|_| MechError { file: file!().to_string(), tokens: vec![], msg: format!("Unsupported argument: {:?}", &arg), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind})
233 }
234 }
235 }
236}
237
238#[macro_export]
239macro_rules! impl_assign_scalar_scalar {
240 ($op_name:tt, $op_fn:tt) => {
241 paste::paste! {
242 #[derive(Debug)]
243 struct [<$op_name AssignSS>]<T> {
244 sink: Ref<T>,
245 source: Ref<T>,
246 }
247 impl<T> MechFunctionFactory for [<$op_name AssignSS>]<T>
248 where
249 T: Debug + Clone + Sync + Send + 'static +
250 $op_name<Output = T> + [<$op_name Assign>] +
251 PartialEq + PartialOrd + CompileConst + ConstElem + AsValueKind,
252 Ref<T>: ToValue
253 {
254 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
255 match args {
256 FunctionArgs::Unary(out, arg1) => {
257 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
258 let sink: Ref<T> = unsafe { out.as_unchecked() }.clone();
259 Ok(Box::new(Self { sink, source }))
260 },
261 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{} requires 2 arguments, got {:?}", stringify!($struct_name), args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
262 }
263 }
264 }
265 impl<T> MechFunctionImpl for [<$op_name AssignSS>]<T>
266 where
267 T: Debug + Clone + Sync + Send + 'static +
268 $op_name<Output = T> + [<$op_name Assign>] +
269 PartialEq + PartialOrd,
270 Ref<T>: ToValue
271 {
272 fn solve(&self) {
273 let sink_ptr = self.sink.as_mut_ptr();
274 let source_ptr = self.source.as_ptr();
275 unsafe {
276 *sink_ptr $op_fn (*source_ptr).clone();
277 }
278 }
279 fn out(&self) -> Value { self.sink.to_value() }
280 fn to_string(&self) -> String { format!("{:#?}", self) }
281 }
282 #[cfg(feature = "compiler")]
283 impl<T> MechFunctionCompiler for [<$op_name AssignSS>]<T>
284 where
285 T: CompileConst + ConstElem + AsValueKind,
286 {
287 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
288 let name = format!("{}AssignSS<{}>", stringify!($op_name), T::as_value_kind());
289 compile_unop!(name, self.sink, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
290 }
291 }
292 register_fxn_descriptor!([<$op_name AssignSS>],
293 u8, "u8",
294 u16, "u16",
295 u32, "u32",
296 u64, "u64",
297 u128, "u128",
298 i8, "i8",
299 i16, "i16",
300 i32, "i32",
301 i64, "i64",
302 i128, "i128",
303 F32, "f32",
304 F64, "f64",
305 R64, "r64",
306 C64, "c64"
307 );
308 }
309 };
310}
311
312#[macro_export]
313macro_rules! impl_assign_vector_vector {
314 ($op_name:tt, $op_fn:tt) => {
315 paste::paste! {
316 #[derive(Debug)]
317 pub struct [<$op_name AssignVV>]<T, MatA, MatB> {
318 pub sink: Ref<MatA>,
319 pub source: Ref<MatB>,
320 _marker: PhantomData<T>,
321 }
322 impl<T, MatA, MatB> MechFunctionFactory for [<$op_name AssignVV>]<T, MatA, MatB>
323 where
324 Ref<MatA>: ToValue,
325 T: Debug + Clone + Sync + Send + 'static + [<$op_name Assign>] +
326 CompileConst + ConstElem + AsValueKind,
327 for<'a> &'a MatA: IntoIterator<Item = &'a T>,
328 for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
329 for<'a> &'a MatB: IntoIterator<Item = &'a T>,
330 MatA: Debug + CompileConst + ConstElem + AsValueKind + 'static,
331 MatB: Debug + CompileConst + ConstElem + AsValueKind + 'static,
332 {
333 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
334 match args {
335 FunctionArgs::Unary(out, arg1) => {
336 let source: Ref<MatB> = unsafe { arg1.as_unchecked() }.clone();
337 let sink: Ref<MatA> = unsafe { out.as_unchecked() }.clone();
338 Ok(Box::new(Self { sink, source, _marker: PhantomData::default() }))
339 },
340 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{} requires 2 arguments, got {:?}", stringify!($struct_name), args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
341 }
342 }
343 }
344 impl<T, MatA, MatB> MechFunctionImpl for [<$op_name AssignVV>]<T, MatA, MatB>
345 where
346 Ref<MatA>: ToValue,
347 T: Debug + Clone + Sync + Send + 'static + [<$op_name Assign>],
348 for<'a> &'a MatA: IntoIterator<Item = &'a T>,
349 for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
350 for<'a> &'a MatB: IntoIterator<Item = &'a T>,
351 MatA: Debug,
352 MatB: Debug,
353 {
354 fn solve(&self) {
355 unsafe {
356 let sink_ptr = self.sink.as_mut_ptr();
357 let source_ptr = self.source.as_ptr();
358 let sink_ref: &mut MatA = &mut *sink_ptr;
359 let source_ref: &MatB = &*source_ptr;
360 for (dst, src) in (&mut *sink_ref).into_iter().zip((&*source_ref).into_iter()) {
361 *dst $op_fn src.clone();
362 }
363 }
364 }
365 fn out(&self) -> Value {self.sink.to_value()}
366 fn to_string(&self) -> String {format!("{:#?}", self)}
367 }
368 #[cfg(feature = "compiler")]
369 impl<T, MatA, MatB> MechFunctionCompiler for [<$op_name AssignVV>]<T, MatA, MatB>
370 where
371 T: CompileConst + ConstElem + AsValueKind,
372 MatA: CompileConst + ConstElem + AsValueKind,
373 MatB: CompileConst + ConstElem + AsValueKind,
374 {
375 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
376 let name = format!("{}AssignVV<{}>", stringify!($op_name), MatA::as_value_kind());
377 compile_unop!(name, self.sink, self.source, ctx, FeatureFlag::Builtin(FeatureKind::OpAssign) );
378 }
379 }
380 impl_register_op_assign_vv_all!([<$op_name AssignVV>]);
381 }
382 };
383}
384
385#[macro_export]
386macro_rules! impl_assign_vector_scalar {
387 ($op_name:tt, $op_fn:tt) => {
388 paste::paste! {
389 #[derive(Debug)]
390 pub struct [<$op_name AssignVS>]<T, MatA> {
391 pub sink: Ref<MatA>,
392 pub source: Ref<T>,
393 _marker: PhantomData<T>,
394 }
395 impl<T, MatA> MechFunctionFactory for [<$op_name AssignVS>]<T, MatA>
396 where
397 Ref<MatA>: ToValue,
398 T: Debug + Clone + Sync + Send + 'static + [<$op_name Assign>] +
399 CompileConst + ConstElem + AsValueKind,
400 for<'a> &'a MatA: IntoIterator<Item = &'a T>,
401 for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
402 MatA: Debug + CompileConst + ConstElem + AsValueKind + 'static,
403 {
404 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
405 match args {
406 FunctionArgs::Binary(out, arg1, arg2) => {
407 let source: Ref<T> = unsafe { arg2.as_unchecked() }.clone();
408 let sink: Ref<MatA> = unsafe { out.as_unchecked() }.clone();
409 Ok(Box::new(Self { sink, source, _marker: PhantomData::default() }))
410 },
411 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{} requires 2 arguments, got {:?}", stringify!($struct_name), args), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments})
412 }
413 }
414 }
415 impl<T, MatA> MechFunctionImpl for [<$op_name AssignVS>]<T, MatA>
416 where
417 Ref<MatA>: ToValue,
418 T: Debug + Clone + Sync + Send + 'static + [<$op_name Assign>],
419 for<'a> &'a MatA: IntoIterator<Item = &'a T>,
420 for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
421 MatA: Debug,
422 {
423 fn solve(&self) {
424 unsafe {
425 let sink_ptr = self.sink.as_mut_ptr();
426 let source_ptr = self.source.as_ptr();
427 let sink_ref: &mut MatA = &mut *sink_ptr;
428 let source_ref: &T = &*source_ptr;
429 for dst in (&mut *sink_ref).into_iter() {
430 *dst $op_fn source_ref.clone();
431 }
432 }
433 }
434 fn out(&self) -> Value {self.sink.to_value()}
435 fn to_string(&self) -> String {format!("{:#?}", self)}
436 }
437 #[cfg(feature = "compiler")]
438 impl<T, MatA> MechFunctionCompiler for [<$op_name AssignVS>]<T, MatA>
439 where
440 T: CompileConst + ConstElem + AsValueKind,
441 MatA: CompileConst + ConstElem + AsValueKind,
442 {
443 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
444 let name = format!("{}AssignVS<{}>", stringify!($op_name), MatA::as_value_kind());
445 compile_unop!(name, self.sink, self.source, ctx, FeatureFlag::Builtin(FeatureKind::OpAssign) );
446 }
447 }
448 }
449 }
450}
451
452#[macro_export]
453macro_rules! register_op_assign_vv {
454 ($op:ident, $type:ty, $size:ty, $size_string:tt) => {
455 paste!{
456 register_descriptor! {
457 FunctionDescriptor {
458 name: concat!(stringify!($op),"<[",stringify!([<$type:lower>]),"]:", $size_string, ">"),
459 ptr: $op::<$type,$size<$type>,$size<$type>>::new,
460 }
461 }
462 }
463 };}
464
465#[macro_export]
466macro_rules! register_op_assign_vv_all {
467 ($op:ident, $ty:ty, $ty_feature:literal) => {
468 #[cfg(feature = "row_vector4")]
469 register_op_assign_vv!($op, $ty, RowVector4, "1,4");
470 #[cfg(feature = "row_vector3")]
471 register_op_assign_vv!($op, $ty, RowVector3, "1,3");
472 #[cfg(feature = "row_vector2")]
473 register_op_assign_vv!($op, $ty, RowVector2, "1,2");
474 #[cfg(feature = "vector2")]
475 register_op_assign_vv!($op, $ty, Vector2, "2,1");
476 #[cfg(feature = "vector3")]
477 register_op_assign_vv!($op, $ty, Vector3, "3,1");
478 #[cfg(feature = "vector4")]
479 register_op_assign_vv!($op, $ty, Vector4, "4,1");
480 #[cfg(feature = "matrix1")]
481 register_op_assign_vv!($op, $ty, Matrix1, "1,1");
482 #[cfg(feature = "matrix2")]
483 register_op_assign_vv!($op, $ty, Matrix2, "2,2");
484 #[cfg(feature = "matrix3")]
485 register_op_assign_vv!($op, $ty, Matrix3, "3,3");
486 #[cfg(feature = "matrix4")]
487 register_op_assign_vv!($op, $ty, Matrix4, "4,4");
488 #[cfg(feature = "matrix2x3")]
489 register_op_assign_vv!($op, $ty, Matrix2x3, "2,3");
490 #[cfg(feature = "matrix3x2")]
491 register_op_assign_vv!($op, $ty, Matrix3x2, "3,2");
492 #[cfg(feature = "vectord")]
493 register_op_assign_vv!($op, $ty, DVector, "0,1");
494 #[cfg(feature = "matrixd")]
495 register_op_assign_vv!($op, $ty, DMatrix, "0,0");
496 #[cfg(feature = "row_vectord")]
497 register_op_assign_vv!($op, $ty, RowDVector, "1,0");
498 };
499}
500
501#[macro_export]
502macro_rules! impl_register_op_assign_vv_all {
503 ($macro_name:ident) => {
504 #[cfg(feature = "u8")]
505 register_op_assign_vv_all!($macro_name, u8, "u8");
506 #[cfg(feature = "u16")]
507 register_op_assign_vv_all!($macro_name, u16, "u16");
508 #[cfg(feature = "u32")]
509 register_op_assign_vv_all!($macro_name, u32, "u32");
510 #[cfg(feature = "u64")]
511 register_op_assign_vv_all!($macro_name, u64, "u64");
512 #[cfg(feature = "u128")]
513 register_op_assign_vv_all!($macro_name, u128, "u128");
514 #[cfg(feature = "i8")]
515 register_op_assign_vv_all!($macro_name, i8, "i8");
516 #[cfg(feature = "i16")]
517 register_op_assign_vv_all!($macro_name, i16, "i16");
518 #[cfg(feature = "i32")]
519 register_op_assign_vv_all!($macro_name, i32, "i32");
520 #[cfg(feature = "i64")]
521 register_op_assign_vv_all!($macro_name, i64, "i64");
522 #[cfg(feature = "i128")]
523 register_op_assign_vv_all!($macro_name, i128, "i128");
524 #[cfg(feature = "f32")]
525 register_op_assign_vv_all!($macro_name, F32, "f32");
526 #[cfg(feature = "f64")]
527 register_op_assign_vv_all!($macro_name, F64, "f64");
528 #[cfg(feature = "r64")]
529 register_op_assign_vv_all!($macro_name, R64, "r64");
530 #[cfg(feature = "c64")]
531 register_op_assign_vv_all!($macro_name, C64, "c64");
532 };
533}
534
535#[macro_export]
536macro_rules! impl_op_assign_value_match_arms {
537 ($op:tt, $arg:expr,$($value_kind:ident, $feature:tt);+ $(;)?) => {
538 paste::paste! {
539 match $arg {
540 $(
541 #[cfg(feature = $feature)]
542 (Value::$value_kind(sink), Value::$value_kind(source)) => Ok(Box::new([<$op AssignSS>]{ sink: sink.clone(), source: source.clone() })),
543 #[cfg(all(feature = $feature, feature = "matrix1"))]
544 (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
545 #[cfg(all(feature = $feature, feature = "matrix2"))]
546 (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
547 #[cfg(all(feature = $feature, feature = "matrix2x3"))]
548 (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
549 #[cfg(all(feature = $feature, feature = "matrix3x2"))]
550 (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
551 #[cfg(all(feature = $feature, feature = "matrix3"))]
552 (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
553 #[cfg(all(feature = $feature, feature = "matrix4"))]
554 (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
555 #[cfg(all(feature = $feature, feature = "matrixd"))]
556 (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
557 #[cfg(all(feature = $feature, feature = "vector2"))]
558 (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
559 #[cfg(all(feature = $feature, feature = "vector3"))]
560 (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
561 #[cfg(all(feature = $feature, feature = "vector4"))]
562 (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
563 #[cfg(all(feature = $feature, feature = "vectord"))]
564 (Value::[<Matrix $value_kind>](Matrix::DVector(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
565 #[cfg(all(feature = $feature, feature = "row_vector2"))]
566 (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
567 #[cfg(all(feature = $feature, feature = "row_vector3"))]
568 (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
569 #[cfg(all(feature = $feature, feature = "row_vector4"))]
570 (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
571 #[cfg(all(feature = $feature, feature = "row_vectord"))]
572 (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)), Value::$value_kind(source)) => Ok(Box::new([<$op AssignVS>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
573 #[cfg(all(feature = $feature, feature = "matrix1"))]
574 (Value::[<Matrix $value_kind>](Matrix::Matrix1(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix1(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
575 #[cfg(all(feature = $feature, feature = "matrix2"))]
576 (Value::[<Matrix $value_kind>](Matrix::Matrix2(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix2(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
577 #[cfg(all(feature = $feature, feature = "matrix2x3"))]
578 (Value::[<Matrix $value_kind>](Matrix::Matrix2x3(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix2x3(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
579 #[cfg(all(feature = $feature, feature = "matrix3x2"))]
580 (Value::[<Matrix $value_kind>](Matrix::Matrix3x2(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix3x2(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
581 #[cfg(all(feature = $feature, feature = "matrix3"))]
582 (Value::[<Matrix $value_kind>](Matrix::Matrix3(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix3(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
583 #[cfg(all(feature = $feature, feature = "matrix4"))]
584 (Value::[<Matrix $value_kind>](Matrix::Matrix4(sink)), Value::[<Matrix $value_kind>](Matrix::Matrix4(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
585 #[cfg(all(feature = $feature, feature = "matrixd"))]
586 (Value::[<Matrix $value_kind>](Matrix::DMatrix(sink)), Value::[<Matrix $value_kind>](Matrix::DMatrix(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
587 #[cfg(all(feature = $feature, feature = "vector2"))]
588 (Value::[<Matrix $value_kind>](Matrix::Vector2(sink)), Value::[<Matrix $value_kind>](Matrix::Vector2(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
589 #[cfg(all(feature = $feature, feature = "vector3"))]
590 (Value::[<Matrix $value_kind>](Matrix::Vector3(sink)), Value::[<Matrix $value_kind>](Matrix::Vector3(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
591 #[cfg(all(feature = $feature, feature = "vector4"))]
592 (Value::[<Matrix $value_kind>](Matrix::Vector4(sink)), Value::[<Matrix $value_kind>](Matrix::Vector4(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
593 #[cfg(all(feature = $feature, feature = "vectord"))]
594 (Value::[<Matrix $value_kind>](Matrix::DVector(sink)), Value::[<Matrix $value_kind>](Matrix::DVector(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
595 #[cfg(all(feature = $feature, feature = "row_vector2"))]
596 (Value::[<Matrix $value_kind>](Matrix::RowVector2(sink)), Value::[<Matrix $value_kind>](Matrix::RowVector2(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
597 #[cfg(all(feature = $feature, feature = "row_vector3"))]
598 (Value::[<Matrix $value_kind>](Matrix::RowVector3(sink)), Value::[<Matrix $value_kind>](Matrix::RowVector3(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
599 #[cfg(all(feature = $feature, feature = "row_vector4"))]
600 (Value::[<Matrix $value_kind>](Matrix::RowVector4(sink)), Value::[<Matrix $value_kind>](Matrix::RowVector4(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
601 #[cfg(all(feature = $feature, feature = "row_vectord"))]
602 (Value::[<Matrix $value_kind>](Matrix::RowDVector(sink)), Value::[<Matrix $value_kind>](Matrix::RowDVector(source))) => Ok(Box::new([<$op AssignVV>]{sink: sink.clone(), source: source.clone(), _marker: PhantomData::default()})),
603 )+
604 x => Err(MechError {file: file!().to_string(),tokens: vec![],msg: format!("Unhandled args {:?}", x),id: line!(),kind: MechErrorKind::UnhandledFunctionArgumentKind,}),
605 }
606 }
607 };
608}