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