1use crate::*;
2use mech_core::*;
3#[cfg(feature = "matrix")]
4use mech_core::matrix::Matrix;
5
6use paste::paste;
7#[cfg(feature = "matrix")]
8use na::{Vector3, DVector, Vector2, Vector4, RowDVector, Matrix1, Matrix3, Matrix4, RowVector3, RowVector4, RowVector2, DMatrix, Rotation3, Matrix2x3, Matrix3x2, Matrix6, Matrix2};
9use std::ops::*;
10use std::fmt::Debug;
11use std::marker::PhantomData;
12#[cfg(any(feature = "num-traits"))]
13use num_traits::*;
14
15#[cfg(feature = "access")]
16pub mod access;
17#[cfg(feature = "assign")]
18pub mod assign;
19#[cfg(feature = "convert")]
20pub mod convert;
21#[cfg(feature = "matrix_horzcat")]
22pub mod horzcat;
23#[cfg(feature = "matrix_vertcat")]
24pub mod vertcat;
25#[cfg(feature = "variable_define")]
26pub mod define;
27
28pub trait LosslessInto<T> {
29 fn lossless_into(self) -> T;
30}
31
32pub trait LossyFrom<T> {
33 fn lossy_from(value: T) -> Self;
34}
35
36#[macro_export]
37macro_rules! impl_range_range_fxn_v {
38 ($struct_name:ident, $op:ident, $ix1:ty, $ix2:ty) => {
39 #[derive(Debug)]
40 pub struct $struct_name<T, MatA, MatB, IxVec1, IxVec2> {
41 pub source: Ref<MatB>,
42 pub ixes: (Ref<IxVec1>,Ref<IxVec2>),
43 pub sink: Ref<MatA>,
44 pub _marker: PhantomData<T>,
45 }
46 impl<T, R1: 'static, C1: 'static, S1: 'static, R2: 'static, C2: 'static, S2: 'static, IxVec1: 'static, IxVec2: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec1, IxVec2>
47 where
48 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
49 Ref<naMatrix<T, R2, C2, S2>>: ToValue,
50 T: Debug + Clone + Sync + Send + 'static +
51 PartialEq + PartialOrd +
52 CompileConst + ConstElem + AsValueKind,
53 IxVec1: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix1]>,
54 IxVec2: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix2]>,
55 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
56 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
57 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
58 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
59 {
60 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
61 match args {
62 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
63 let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
64 let ix1: Ref<IxVec1> = unsafe { arg2.as_unchecked() }.clone();
65 let ix2: Ref<IxVec2> = unsafe { arg3.as_unchecked() }.clone();
66 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
67 Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData::default() }))
68 },
69 _ => Err(MechError2::new(
70 IncorrectNumberOfArguments { expected: 3, found: args.len() },
71 None
72 ).with_compiler_loc())
73 }
74 }
75 }
76 impl<T, R1, C1, S1, R2, C2, S2, IxVec1, IxVec2>
77 MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec1, IxVec2>
78 where
79 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
80 T: Debug + Clone + Sync + Send + 'static +
81 PartialEq + PartialOrd,
82 IxVec1: AsRef<[$ix1]> + Debug,
83 IxVec2: AsRef<[$ix2]> + Debug,
84 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
85 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
86 {
87 fn solve(&self) {
88 unsafe {
89 let sink = &mut *self.sink.as_mut_ptr();
90 let source = &*self.source.as_ptr();
91 let ix1 = (*self.ixes.0.as_ptr()).as_ref();
92 let ix2 = (*self.ixes.1.as_ptr()).as_ref();
93 $op!(sink, ix1, ix2, source);
94 }
95 }
96 fn out(&self) -> Value {self.sink.to_value()}
97 fn to_string(&self) -> String {format!("{:#?}", self)}
98 }
99 #[cfg(feature = "compiler")]
100 impl<T, R1, C1, S1, R2, C2, S2, IxVec1, IxVec2> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec1, IxVec2>
101 where
102 T: CompileConst + ConstElem + AsValueKind,
103 IxVec1: CompileConst + ConstElem + AsNaKind,
104 IxVec2: CompileConst + ConstElem + AsNaKind,
105 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
106 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
107 {
108 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
109 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(), IxVec1::as_na_kind(), IxVec2::as_na_kind());
110 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
111 }
112 }
113 };}
114
115#[macro_export]
116macro_rules! impl_all_fxn_v {
117 ($struct_name:ident, $op:ident, $ix:ty) => {
118 #[derive(Debug)]
119 pub struct $struct_name<T, MatA, MatB, IxVec> {
120 pub source: Ref<MatB>,
121 pub ixes: Ref<IxVec>,
122 pub sink: Ref<MatA>,
123 pub _marker: PhantomData<T>,
124 }
125 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>
126 where
127 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
128 Ref<naMatrix<T, R2, C2, S2>>: ToValue,
129 T: Debug + Clone + Sync + Send + 'static +
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 impl<T, R1, C1, S1, R2, C2, S2, IxVec>
154 MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
155 where
156 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
157 T: Debug + Clone + Sync + Send + 'static +
158 PartialEq + PartialOrd,
159 IxVec: AsRef<[$ix]> + Debug,
160 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
161 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
162 {
163 fn solve(&self) {
164 unsafe {
165 let sink_ptr = &mut *self.sink.as_mut_ptr();
166 let source_ptr = &*self.source.as_ptr();
167 let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
168 $op!(source_ptr,ix_ptr,sink_ptr);
169 }
170 }
171 fn out(&self) -> Value {self.sink.to_value()}
172 fn to_string(&self) -> String {format!("{:#?}", self)}
173 }
174 #[cfg(feature = "compiler")]
175 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>
176 where
177 T: CompileConst + ConstElem + AsValueKind,
178 IxVec: CompileConst + ConstElem + AsNaKind,
179 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
180 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
181 {
182 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
183 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());
184 compile_binop!(name, self.sink, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::OpAssign));
185 }
186 }
187 };}