1#[macro_use]
2use crate::stdlib::*;
3use std::marker::PhantomData;
4use std::fmt::Debug;
5use nalgebra::{
6 IsContiguous,
7 base::{Matrix as naMatrix, Storage, StorageMut},
8 Dim, Scalar,
9};
10
11#[macro_export]
14macro_rules! impl_set_match_arms {
15 ($fxn_name:ident,$macro_name:ident, $arg:expr) => {
16 paste!{
17 [<impl_set_ $macro_name _match_arms>]!(
18 $fxn_name,
19 $arg,
20 Bool, "bool";
21 U8, "u8";
22 U16, "u16";
23 U32, "u32";
24 U64, "u64";
25 U128, "u128";
26 I8, "i8";
27 I16, "i16";
28 I32, "i32";
29 I64, "i64";
30 U128, "u128";
31 F32, "f32";
32 F64, "f64" ;
33 String, "string";
34 C64, "complex";
35 R64, "rational";
36 )
37 }
38 }
39}
40
41#[macro_export]
42macro_rules! impl_set_all_fxn_s {
43 ($struct_name:ident, $op:ident, $ix:ty) => {
44 #[derive(Debug)]
45 pub struct $struct_name<T, MatA, IxVec> {
46 pub source: Ref<T>,
47 pub ixes: Ref<IxVec>,
48 pub sink: Ref<MatA>,
49 pub _marker: PhantomData<T>,
50 }
51 impl<T, R1, C1, S1: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
52 where
53 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
54 T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
55 IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
56 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
57 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
58 {
59 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
60 match args {
61 FunctionArgs::Binary(out, arg1, arg2) => {
62 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
63 let ixes: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
64 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
65 Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
66 },
67 _ => Err(MechError2::new(
68 IncorrectNumberOfArguments { expected: 2, found: args.len() },
69 None
70 ).with_compiler_loc()
71 ),
72 }
73 }
74 }
75 impl<T, R1, C1, S1, IxVec> MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
76 where
77 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
78 T: Scalar + Clone + Debug + Sync + Send + 'static,
79 IxVec: AsRef<[$ix]> + Debug,
80 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
81 {
82 fn solve(&self) {
83 unsafe {
84 let sink_ptr = &mut *self.sink.as_mut_ptr();
85 let source_ptr = &*self.source.as_ptr();
86 let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
87 $op!(source_ptr,ix_ptr,sink_ptr);
88 }
89 }
90 fn out(&self) -> Value {self.sink.to_value()}
91 fn to_string(&self) -> String {format!("{:#?}", self)}
92 }
93 #[cfg(feature = "compiler")]
94 impl<T, R1, C1, S1, IxVec> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
95 where
96 T: CompileConst + ConstElem + AsValueKind,
97 IxVec: CompileConst + ConstElem + AsNaKind,
98 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
99 {
100 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
101 let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind(), IxVec::as_na_kind());
102 compile_binop!(name, self.sink, self.ixes, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
103 }
104 }};}
105
106#[macro_export]
109macro_rules! assign_1d_scalar {
110 ($source:expr, $ix:expr, $sink:expr) => {
111 ($sink)[$ix - 1] = ($source).clone();
112 };}
113
114#[macro_export]
115macro_rules! assign_1d_scalar_b {
116 ($source:expr, $ix:expr, $sink:expr) => {
117 if $ix {
118 for ix in 0..$sink.len() {
119 $sink[ix] = $source.clone();
120 }
121 }
122 };}
123
124#[macro_export]
125macro_rules! assign_1d_scalar_vb {
126 ($source:expr, $ix:expr, $sink:expr) => {
127 if *$ix {
128 let len = $sink.len().min($source.len());
129 for ix in 0..len {
130 $sink[ix] = $source[ix].clone();
131 }
132 }
133 };}
134
135#[macro_export]
136macro_rules! impl_assign_fxn_s {
137 ($struct_name:ident, $op:ident, $ix:ty) => {
138 #[derive(Debug)]
139 pub struct $struct_name<T, MatA> {
140 pub source: Ref<T>,
141 pub ixes: Ref<$ix>,
142 pub sink: Ref<MatA>,
143 pub _marker: PhantomData<T>,
144 }
145 impl<T, R, C, S: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R, C, S>>
146 where
147 Ref<naMatrix<T, R, C, S>>: ToValue,
148 T: Scalar + Clone + Debug + Sync + Send + 'static +
149 CompileConst + ConstElem + AsValueKind,
150 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
151 naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
152 {
153 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
154 match args {
155 FunctionArgs::Binary(out, arg1, arg2) => {
156 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
157 let ixes: Ref<$ix> = unsafe { arg2.as_unchecked() }.clone();
158 let sink: Ref<naMatrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
159 Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
160 },
161 _ => Err(MechError2::new(
162 IncorrectNumberOfArguments { expected: 2, found: args.len() },
163 None
164 ).with_compiler_loc()
165 ),
166 }
167 }
168 }
169 impl<T, R, C, S> MechFunctionImpl for $struct_name<T, naMatrix<T, R, C, S>>
170 where
171 Ref<naMatrix<T, R, C, S>>: ToValue,
172 T: Scalar + Clone + Debug + Sync + Send + 'static,
173 R: Dim,
174 C: Dim,
175 S: StorageMut<T, R, C> + Clone + Debug,
176 {
177 fn solve(&self) {
178 unsafe {
179 let mut sink_ptr = &mut *self.sink.as_mut_ptr();
180 let ix_val = (*self.ixes.as_ptr()).clone();
181 let source_val = (*self.source.as_ptr()).clone();
182 $op!(source_val, ix_val, sink_ptr);
183 }
184 }
185 fn out(&self) -> Value {self.sink.to_value()}
186 fn to_string(&self) -> String {format!("{:#?}", self)}
187 }
188 #[cfg(feature = "compiler")]
189 impl<T, R, C, S> MechFunctionCompiler for $struct_name<T, naMatrix<T, R, C, S>>
190 where
191 T: CompileConst + ConstElem + AsValueKind,
192 naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
193 {
194 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
195 let name = format!("{}<{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind());
196 compile_binop!(name, self.sink, self.ixes, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
197 }
198 }};}
199
200impl_assign_fxn_s!(Assign1DS, assign_1d_scalar, usize);
201impl_assign_fxn_s!(Assign1DB, assign_1d_scalar_b, bool);
202impl_assign_scalar_fxn_v!(Assign1DVB, assign_1d_scalar_vb, bool);
203
204fn impl_assign_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
205 let arg = (sink.clone(), ixes.as_slice(), source.clone());
206 impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u8, "u8")
207 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u16, "u16"))
208 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u32, "u32"))
209 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u64, "u64"))
210 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u128, "u128"))
211 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i8, "i8"))
212 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i16, "i16"))
213 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i32, "i32"))
214 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i64, "i64"))
215 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i128, "i128"))
216 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, f32, "f32"))
217 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, f64, "f64"))
218 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, R64, "rational"))
219 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, C64, "complex"))
220 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, bool, "bool"))
221 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, String, "string"))
222
223 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u8, "u8"))
224 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u16, "u16"))
225 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u32, "u32"))
226 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u64, "u64"))
227 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u128, "u128"))
228 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i8, "i8"))
229 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i16, "i16"))
230 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i32, "i32"))
231 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i64, "i64"))
232 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i128, "i128"))
233 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, f32, "f32"))
234 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, f64, "f64"))
235 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, R64, "rational"))
236 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, C64, "complex"))
237 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, bool, "bool"))
238 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, String, "string"))
239 .map_err(|_| MechError2::new(
240 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
241 None
242 ).with_compiler_loc()
243 )
244}
245
246pub struct MatrixAssignScalar {}
247impl NativeFunctionCompiler for MatrixAssignScalar {
248 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
249 if arguments.len() <= 1 {
250 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
251 }
252 let sink: Value = arguments[0].clone();
253 let source: Value = arguments[1].clone();
254 let ixes = arguments.clone().split_off(2);
255 match impl_assign_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
256 Ok(fxn) => Ok(fxn),
257 Err(x) => {
258 match sink {
259 Value::MutableReference(sink) => { impl_assign_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
260 sink => Err(MechError2::new(
261 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
262 None
263 ).with_compiler_loc()
264 ),
265 }
266 }
267 }
268 }
269}
270
271macro_rules! set_1d_range {
274 ($source:expr, $ix:expr, $sink:expr) => {
275 unsafe {
276 for i in 0..($ix).len() {
277 ($sink)[($ix)[i] - 1] = ($source).clone();
278 }
279 }
280 };}
281
282macro_rules! set_1d_range_b {
283 ($source:expr, $ix:expr, $sink:expr) => {
284 unsafe {
285 for i in 0..($ix).len() {
286 if $ix[i] == true {
287 ($sink)[i] = ($source).clone();
288 }
289 }
290 }
291 };}
292
293macro_rules! set_1d_range_vec {
294 ($source:expr, $ix:expr, $sink:expr) => {
295 unsafe {
296 for i in 0..($ix).len() {
297 ($sink)[($ix)[i] - 1] = ($source)[i].clone();
298 }
299 }
300 };}
301
302macro_rules! set_1d_range_vec_b {
303 ($source:expr, $ix:expr, $sink:expr) => {
304 unsafe {
305 for i in 0..($ix).len() {
306 if $ix[i] == true {
307 ($sink)[i] = ($source)[i].clone();
308 }
309 }
310 }};}
311
312impl_set_all_fxn_s!(Assign1DRS,set_1d_range,usize);
313impl_set_all_fxn_s!(Assign1DRB,set_1d_range_b,bool);
314impl_all_fxn_v!(Assign1DRV,set_1d_range_vec,usize);
315impl_all_fxn_v!(Assign1DRVB,set_1d_range_vec_b,bool);
316
317fn impl_assign_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
318 let arg = (sink.clone(), ixes.as_slice(), source.clone());
319 impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u8, "u8")
320 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u16, "u16"))
321 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u32, "u32"))
322 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u64, "u64"))
323 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u128, "u128"))
324 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i8, "i8"))
325 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i16, "i16"))
326 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i32, "i32"))
327 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i64, "i64"))
328 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i128, "i128"))
329 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, f32, "f32"))
330 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, f64, "f64"))
331 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, R64, "rational"))
332 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, C64, "complex"))
333 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, bool, "bool"))
334 .or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, String, "string"))
335
336 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u8, "u8"))
337 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u16, "u16"))
338 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u32, "u32"))
339 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u64, "u64"))
340 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u128, "u128"))
341 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i8, "i8"))
342 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i16, "i16"))
343 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i32, "i32"))
344 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i64, "i64"))
345 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i128, "i128"))
346 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, f32, "f32"))
347 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, f64, "f64"))
348 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, R64, "rational"))
349 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, C64, "complex"))
350 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, bool, "bool"))
351 .or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, String, "string"))
352 .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRange".to_string() }, None).with_compiler_loc())
353}
354
355pub struct MatrixAssignRange {}
356impl NativeFunctionCompiler for MatrixAssignRange {
357 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
358 if arguments.len() <= 1 {
359 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
360 }
361 let sink: Value = arguments[0].clone();
362 let source: Value = arguments[1].clone();
363 let ixes = arguments.clone().split_off(2);
364 match impl_assign_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
365 Ok(fxn) => Ok(fxn),
366 Err(x) => {
367 match (sink.clone(),&ixes,source.clone()) {
368 (Value::MutableReference(sink),_,Value::MutableReference(source)) => { impl_assign_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
369 (sink,_,Value::MutableReference(source)) => { impl_assign_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
370 (Value::MutableReference(sink),_,source) => { impl_assign_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
371 (sink, ixes, source) => Err(MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRange".to_string() }, None).with_compiler_loc()),
372 }
373 }
374 }
375 }
376}
377
378#[derive(Debug)]
381pub struct Set1DAS<T, Sink> {
382 pub source: Ref<T>,
383 pub sink: Ref<Sink>,
384 pub _marker: PhantomData<T>,
385}
386impl<T, R, C, S> MechFunctionFactory for Set1DAS<T, naMatrix<T, R, C, S>>
387where
388 Ref<naMatrix<T, R, C, S>>: ToValue,
389 T: Debug + Clone + Sync + Send + PartialEq + 'static +
390 CompileConst + ConstElem + AsValueKind,
391 R: Dim,
392 C: Dim,
393 S: StorageMut<T, R, C> + Debug + IsContiguous + 'static,
394 naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
395{
396 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
397 match args {
398 FunctionArgs::Unary(out, arg1) => {
399 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
400 let sink: Ref<naMatrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
401 Ok(Box::new(Self { sink, source, _marker: PhantomData::default() }))
402 },
403 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: args.len() }, None).with_compiler_loc())
404 }
405 }
406}
407impl<T, R, C, S> MechFunctionImpl for Set1DAS<T, naMatrix<T, R, C, S>>
408where
409 T: Debug + Clone + Sync + Send + PartialEq + 'static,
410 R: Dim,
411 C: Dim,
412 S: StorageMut<T, R, C> + Debug + IsContiguous,
413 Ref<naMatrix<T, R, C, S>>: ToValue,
414{
415 fn solve(&self) {
416 unsafe {
417 let sink = &mut *self.sink.as_mut_ptr();
418 let source_val = (*self.source.as_ptr()).clone();
419 let slice = sink.as_mut_slice();
420 for elem in slice.iter_mut() {
421 *elem = source_val.clone();
422 }
423 }
424 }
425 fn out(&self) -> Value {self.sink.to_value()}
426 fn to_string(&self) -> String {format!("{:#?}", self)}
427}
428#[cfg(feature = "compiler")]
429impl<T, R, C, S> MechFunctionCompiler for Set1DAS<T, naMatrix<T, R, C, S>>
430where
431 T: CompileConst + ConstElem + AsValueKind,
432 naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
433{
434 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
435 let name = format!("Set1DAS<{}{}>", T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind());
436 compile_unop!(name, self.sink, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
437 }
438}
439
440fn impl_assign_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
441 let arg = (sink.clone(), ixes.as_slice(), source.clone());
442 impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u8, "u8")
443 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u16, "u16"))
444 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u32, "u32"))
445 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u64, "u64"))
446 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u128, "u128"))
447 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i8, "i8"))
448 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i16, "i16"))
449 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i32, "i32"))
450 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i64, "i64"))
451 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i128, "i128"))
452 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, f32, "f32"))
453 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, f64, "f64"))
454 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, R64, "rational"))
455 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, C64, "complex"))
456 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, bool, "bool"))
457 .or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, String, "string"))
458 .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignAll".to_string() }, None).with_compiler_loc())
459}
460
461pub struct MatrixAssignAll {}
462impl NativeFunctionCompiler for MatrixAssignAll {
463 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
464 if arguments.len() <= 1 {
465 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
466 }
467 let sink: Value = arguments[0].clone();
468 let source: Value = arguments[1].clone();
469 let ixes = arguments.clone().split_off(2);
470 match impl_assign_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
471 Ok(fxn) => Ok(fxn),
472 Err(_) => {
473 match sink {
474 Value::MutableReference(sink) => { impl_assign_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
475 _ => Err(MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignAll".to_string() }, None).with_compiler_loc()),
476 }
477 }
478 }
479 }
480}
481
482#[derive(Debug)]
485pub struct Assign2DSSS<T, MatA> {
486 pub source: Ref<T>,
487 pub ixes: (Ref<usize>, Ref<usize>),
488 pub sink: Ref<MatA>,
489 pub _marker: PhantomData<T>,
490}
491impl<T, R1, C1, S1: 'static> MechFunctionFactory for Assign2DSSS<T, naMatrix<T, R1, C1, S1>>
492where
493 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
494 T: Scalar + Clone + Debug + Sync + Send + 'static +
495 CompileConst + ConstElem + AsValueKind,
496 R1: Dim,
497 C1: Dim,
498 S1: StorageMut<T, R1, C1> + Clone + Debug,
499 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
500{
501 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
502 match args {
503 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
504 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
505 let ix1: Ref<usize> = unsafe { arg2.as_unchecked() }.clone();
506 let ix2: Ref<usize> = unsafe { arg3.as_unchecked() }.clone();
507 let sink: Ref<naMatrix<T, R1, C1, S1>> =
508 unsafe { out.as_unchecked() }.clone();
509 Ok(Box::new(Self {sink,source,ixes: (ix1, ix2),_marker: PhantomData}))
510 }
511 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc()),
512 }
513 }
514}
515impl<T, R1, C1, S1> MechFunctionImpl for Assign2DSSS<T, naMatrix<T, R1, C1, S1>>
516where
517 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
518 T: Scalar + Clone + Debug + Sync + Send + 'static,
519 R1: Dim,
520 C1: Dim,
521 S1: StorageMut<T, R1, C1> + Clone + Debug,
522{
523 fn solve(&self) {
524 unsafe {
525 let sink_ptr = &mut *self.sink.as_mut_ptr();
526 let source_val = (*self.source.as_ptr()).clone();
527 let r = (*self.ixes.0.as_ptr()).clone();
528 let c = (*self.ixes.1.as_ptr()).clone();
529 sink_ptr[(r - 1, c - 1)] = source_val;
530 }
531 }
532 fn out(&self) -> Value {self.sink.to_value()}
533 fn to_string(&self) -> String {format!("{:#?}", self)}
534}
535impl<T, R1, C1, S1> MechFunctionCompiler for Assign2DSSS<T, naMatrix<T, R1, C1, S1>>
536where
537 T: CompileConst + ConstElem + AsValueKind,
538 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
539{
540 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
541 let name = format!("Assign2DSSS<{}{}>", T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind());
542 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
543 }
544}
545
546fn impl_assign_scalar_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
547 let arg = (sink.clone(), ixes.as_slice(), source.clone());
548 impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u8, "u8")
549 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u16, "u16"))
550 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u32, "u32"))
551 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u64, "u64"))
552 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u128, "u128"))
553 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i8, "i8"))
554 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i16, "i16"))
555 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i32, "i32"))
556 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i64, "i64"))
557 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i128, "i128"))
558 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, f32, "f32"))
559 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, f64, "f64"))
560 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, R64, "rational"))
561 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, C64, "complex"))
562 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, bool, "bool"))
563 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, String, "string"))
564 .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignScalarScalar".to_string() }, None).with_compiler_loc())
565}
566
567pub struct MatrixAssignScalarScalar {}
568impl NativeFunctionCompiler for MatrixAssignScalarScalar {
569 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
570 if arguments.len() <= 1 {
571 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
572 }
573 let sink: Value = arguments[0].clone();
574 let source: Value = arguments[1].clone();
575 let ixes = arguments.clone().split_off(2);
576 match impl_assign_scalar_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
577 Ok(fxn) => Ok(fxn),
578 Err(_) => {
579 match sink {
580 Value::MutableReference(sink) => { impl_assign_scalar_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
581 _ => Err(MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignScalarScalar".to_string() }, None).with_compiler_loc()),
582 }
583 }
584 }
585 }
586}
587
588macro_rules! assign_2d_all_scalar {
591 ($source:expr, $ix:expr, $sink:expr) => {
592 for i in 0..$sink.nrows() {
593 ($sink).column_mut($ix - 1)[i] = ($source).clone();
594 }
595 };}
596
597macro_rules! assign_2d_all_vector {
598 ($source:expr, $ix:expr, $sink:expr) => {
599 for i in 0..$sink.nrows() {
600 ($sink).column_mut($ix - 1)[i] = ($source)[i].clone();
601 }
602 };}
603
604#[macro_export]
605macro_rules! impl_assign_scalar_fxn_v {
606 ($struct_name:ident, $op:ident, $ix:ty) => {
607 #[derive(Debug)]
608 pub struct $struct_name<T, MatA, MatB> {
609 pub source: Ref<MatB>,
610 pub ixes: Ref<$ix>,
611 pub sink: Ref<MatA>,
612 pub _marker: PhantomData<T>,
613 }
614 impl<T, R1: 'static, C1: 'static, S1: 'static, R2: 'static, C2: 'static, S2: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>>
615 where
616 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
617 Ref<naMatrix<T, R2, C2, S2>>: ToValue,
618 T: Debug + Clone + Sync + Send + 'static +
619 PartialEq + PartialOrd +
620 CompileConst + ConstElem + AsValueKind,
621 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
622 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
623 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
624 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
625 {
626 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
627 match args {
628 FunctionArgs::Binary(out, arg1, arg2) => {
629 let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
630 let ixes: Ref<$ix> = unsafe { arg2.as_unchecked() }.clone();
631 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
632 Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
633 },
634 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
635 }
636 }
637 }
638 impl<T, R1, C1, S1, R2, C2, S2>
639 MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>>
640 where
641 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
642 T: Debug + Clone + Sync + Send + 'static +
643 PartialEq + PartialOrd,
644 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
645 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
646 {
647 fn solve(&self) {
648 unsafe {
649 let sink_ptr = &mut *self.sink.as_mut_ptr();
650 let source_ptr = &*self.source.as_ptr();
651 let ix_ptr = &(*self.ixes.as_ptr());
652 $op!(source_ptr,ix_ptr,sink_ptr);
653 }
654 }
655 fn out(&self) -> Value {self.sink.to_value()}
656 fn to_string(&self) -> String {format!("{:#?}", self)}
657 }
658 #[cfg(feature = "compiler")]
659 impl<T, R1, C1, S1, R2, C2, S2> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>>
660 where
661 T: CompileConst + ConstElem + AsValueKind,
662 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
663 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
664 {
665 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
666 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());
667 compile_binop!(name, self.sink, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
668 }
669 }
670 };}
671
672impl_assign_fxn_s!(Assign2DASS, assign_2d_all_scalar, usize);
673impl_assign_scalar_fxn_v!(Assign2DASV, assign_2d_all_vector, usize);
674
675fn impl_assign_all_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
676 let arg = (sink.clone(), ixes.as_slice(), source.clone());
677 impl_assign_all_scalar_arms!(Assign2DAS, &arg, u8, "u8")
678 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u16, "u16"))
679 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u32, "u32"))
680 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u64, "u64"))
681 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u128, "u128"))
682 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i8, "i8"))
683 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i16, "i16"))
684 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i32, "i32"))
685 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i64, "i64"))
686 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i128, "i128"))
687 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, f32, "f32"))
688 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, f64, "f64"))
689 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, R64, "rational"))
690 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, C64, "complex"))
691 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, bool, "bool"))
692 .or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, String, "string"))
693 .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc())
694}
695
696pub struct MatrixAssignAllScalar {}
697impl NativeFunctionCompiler for MatrixAssignAllScalar {
698 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
699 if arguments.len() <= 1 {
700 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
701 }
702 let sink: Value = arguments[0].clone();
703 let source: Value = arguments[1].clone();
704 let ixes = arguments.clone().split_off(2);
705 match impl_assign_all_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
706 Ok(fxn) => Ok(fxn),
707 Err(x) => {
708 match sink {
709 Value::MutableReference(sink) => { impl_assign_all_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
710 sink => Err(MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc()),
711 }
712 }
713 }
714 }
715}
716
717macro_rules! assign_2d_scalar_all_scalar {
720 ($source:expr, $ix:expr, $sink:expr) => {
721 for i in 0..$sink.ncols() {
722 ($sink).row_mut($ix - 1)[i] = ($source).clone();
723 }
724 };}
725
726macro_rules! assign_2d_scalar_all_vector {
727 ($source:expr, $ix:expr, $sink:expr) => {
728 for i in 0..$sink.ncols() {
729 ($sink).row_mut($ix - 1)[i] = ($source)[i].clone();
730 }
731 };}
732
733impl_assign_fxn_s!(Assign2DSAS, assign_2d_scalar_all_scalar, usize);
734impl_assign_scalar_fxn_v!(Assign2DSAV, assign_2d_scalar_all_vector, usize);
735
736fn impl_assign_scalar_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
737 let arg = (sink.clone(), ixes.as_slice(), source.clone());
738 impl_assign_scalar_all_arms!(Assign2DSA, &arg, u8, "u8")
739 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u16, "u16"))
740 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u32, "u32"))
741 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u64, "u64"))
742 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u128, "u128"))
743 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i8, "i8"))
744 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i16, "i16"))
745 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i32, "i32"))
746 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i64, "i64"))
747 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i128, "i128"))
748 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, f32, "f32"))
749 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, f64, "f64"))
750 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, R64, "rational"))
751 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, C64, "complex"))
752 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, bool, "bool"))
753 .or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, String, "string"))
754 .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc())
755}
756
757pub struct MatrixAssignScalarAll {}
758impl NativeFunctionCompiler for MatrixAssignScalarAll {
759 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
760 if arguments.len() <= 1 {
761 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
762 }
763 let sink: Value = arguments[0].clone();
764 let source: Value = arguments[1].clone();
765 let ixes = arguments.clone().split_off(2);
766 match impl_assign_scalar_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
767 Ok(fxn) => Ok(fxn),
768 Err(_) => {
769 match sink {
770 Value::MutableReference(sink) => { impl_assign_scalar_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
771 _ => Err(MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc()),
772 }
773 }
774 }
775 }
776}
777
778macro_rules! assign_2d_range_scalar {
781 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
782 unsafe {
783 let mut col = ($sink).column_mut($ix2 - 1);
784 for &rix in ($ix1).iter() {
785 col[rix - 1] = ($source).clone();
786 }
787 }
788 };
789}
790
791macro_rules! assign_2d_range_scalar_v {
792 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
793 unsafe {
794 let mut col = ($sink).column_mut($ix2 - 1);
795 for (i, &rix) in ($ix1).iter().enumerate() {
796 col[rix - 1] = ($source)[i].clone();
797 }
798 }
799 };
800}
801
802macro_rules! assign_2d_range_scalar_b {
803 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
804 unsafe {
805 let mut col = ($sink).column_mut($ix2 - 1);
806 for (rix, &is_selected) in ($ix1).iter().enumerate() {
807 if is_selected {
808 col[rix] = ($source).clone();
809 }
810 }
811 }
812 };
813}
814
815macro_rules! assign_2d_range_scalar_vb {
816 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
817 unsafe {
818 let mut col = ($sink).column_mut($ix2 - 1);
819 for (rix, &is_selected) in ($ix1).iter().enumerate() {
820 if is_selected {
821 col[rix] = ($source)[rix].clone();
822 }
823 }
824 }
825 };
826}
827
828#[macro_export]
829macro_rules! impl_assign_range_scalar_fxn_s {
830 ($struct_name:ident, $op:tt, $ix:ty) => {
831 #[derive(Debug)]
832 pub struct $struct_name<T, MatA, IxVec> {
833 pub source: Ref<T>,
834 pub ixes: (Ref<IxVec>, Ref<usize>),
835 pub sink: Ref<MatA>,
836 pub _marker: PhantomData<T>,
837 }
838 impl<T, R, C, S: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
839 where
840 Ref<naMatrix<T, R, C, S>>: ToValue,
841 T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
842 IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
843 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
844 naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
845 {
846 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
847 match args {
848 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
849 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
850 let ix1: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
851 let ix2: Ref<usize> = unsafe { arg3.as_unchecked() }.clone();
852 let sink: Ref<na::Matrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
853 Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData }))
854 }
855 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
856 }
857 }
858 }
859 impl<T, R, C, S, IxVec> MechFunctionImpl for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
860 where
861 Ref<naMatrix<T, R, C, S>>: ToValue,
862 T: Scalar + Clone + Debug + Sync + Send + 'static,
863 IxVec: AsRef<[$ix]> + Debug,
864 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
865 {
866 fn solve(&self) {
867 unsafe {
868 let sink = &mut *self.sink.as_mut_ptr();
869 let source = &*self.source.as_ptr();
870 let ix1 = (*self.ixes.0.as_ptr()).as_ref();
871 let ix2 = (*self.ixes.1.as_ptr());
872 $op!(sink, ix1, ix2, source);
873 }
874 }
875 fn out(&self) -> Value {self.sink.to_value()}
876 fn to_string(&self) -> String {format!("{:#?}", self)}
877 }
878 #[cfg(feature = "compiler")]
879 impl<T, R, C, S, IxVec> MechFunctionCompiler for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
880 where
881 T: CompileConst + ConstElem + AsValueKind,
882 IxVec: CompileConst + ConstElem + AsNaKind,
883 naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
884 {
885 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
886 let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind(), IxVec::as_na_kind());
887 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
888 }
889 }
890 };}
891
892#[macro_export]
893macro_rules! impl_assign_range_scalar_fxn_v {
894 ($struct_name:ident, $op:ident, $ix:ty) => {
895 #[derive(Debug)]
896 pub struct $struct_name<T, MatA, MatB, IxVec> {
897 pub source: Ref<MatB>,
898 pub ixes: (Ref<IxVec>, Ref<usize>),
899 pub sink: Ref<MatA>,
900 pub _marker: PhantomData<T>,
901 }
902 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>
903 where
904 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
905 Ref<naMatrix<T, R2, C2, S2>>: ToValue,
906 T: Debug + Clone + Sync + Send + 'static +
907 PartialEq + PartialOrd +
908 CompileConst + ConstElem + AsValueKind,
909 IxVec: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix]>,
910 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
911 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
912 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
913 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
914 {
915 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
916 match args {
917 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
918 let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
919 let ix1: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
920 let ix2: Ref<usize> = unsafe { arg3.as_unchecked() }.clone();
921 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
922 Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData::default() }))
923 },
924 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
925 }
926 }
927 }
928 impl<T, R1, C1, S1, R2, C2, S2, IxVec>
929 MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
930 where
931 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
932 T: Debug + Clone + Sync + Send + 'static +
933 PartialEq + PartialOrd,
934 IxVec: AsRef<[$ix]> + Debug,
935 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
936 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
937 {
938 fn solve(&self) {
939 unsafe {
940 let sink = &mut *self.sink.as_mut_ptr();
941 let source = &*self.source.as_ptr();
942 let ix1 = (*self.ixes.0.as_ptr()).as_ref();
943 let ix2 = (*self.ixes.1.as_ptr());
944 $op!(sink, ix1, ix2, source);
945 }
946 }
947 fn out(&self) -> Value {self.sink.to_value()}
948 fn to_string(&self) -> String {format!("{:#?}", self)}
949 }
950 #[cfg(feature = "compiler")]
951 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>
952 where
953 T: CompileConst + ConstElem + AsValueKind,
954 IxVec: CompileConst + ConstElem + AsNaKind,
955 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
956 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
957 {
958 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
959 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());
960 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
961 }
962 }
963 };}
964
965impl_assign_range_scalar_fxn_s!(Assign2DSSMD, assign_2d_range_scalar, usize);
966
967impl_assign_range_scalar_fxn_s!(Assign2DRSS, assign_2d_range_scalar, usize);
968impl_assign_range_scalar_fxn_s!(Assign2DRSB, assign_2d_range_scalar_b, bool);
969impl_assign_range_scalar_fxn_v!(Assign2DRSV, assign_2d_range_scalar_v, usize);
970impl_assign_range_scalar_fxn_v!(Assign2DRSVB, assign_2d_range_scalar_vb, bool);
971
972fn impl_assign_range_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
973 let arg = (sink.clone(), ixes.as_slice(), source.clone());
974 impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u8, "u8")
975 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u16, "u16"))
976 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u32, "u32"))
977 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u64, "u64"))
978 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u128, "u128"))
979 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i8, "i8"))
980 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i16, "i16"))
981 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i32, "i32"))
982 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i64, "i64"))
983 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i128, "i128"))
984 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, f32, "f32"))
985 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, f64, "f64"))
986 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, R64, "rational"))
987 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, C64, "complex"))
988 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, bool, "bool"))
989 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, String, "string"))
990
991 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u8, "u8"))
992 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u16, "u16"))
993 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u32, "u32"))
994 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u64, "u64"))
995 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u128, "u128"))
996 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i8, "i8"))
997 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i16, "i16"))
998 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i32, "i32"))
999 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i64, "i64"))
1000 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i128, "i128"))
1001 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, f32, "f32"))
1002 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, f64, "f64"))
1003 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, R64, "rational"))
1004 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, C64, "complex"))
1005 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, bool, "bool"))
1006 .or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, String, "string"))
1007 .map_err(|_| MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc())
1008}
1009
1010pub struct MatrixAssignRangeScalar {}
1011impl NativeFunctionCompiler for MatrixAssignRangeScalar {
1012 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1013 if arguments.len() <= 1 {
1014 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1015 }
1016 let sink: Value = arguments[0].clone();
1017 let source: Value = arguments[1].clone();
1018 let ixes = arguments.clone().split_off(2);
1019 match impl_assign_range_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
1020 Ok(fxn) => Ok(fxn),
1021 Err(_) => {
1022 match sink {
1023 Value::MutableReference(sink) => { impl_assign_range_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
1024 _ => Err(MechError2::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc()),
1025 }
1026 }
1027 }
1028 }
1029}
1030
1031macro_rules! assign_2d_scalar_range {
1034 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1035 unsafe {
1036 for i in 0..($ix2).len() {
1037 let cix = $ix2[i] - 1;
1038 ($sink).row_mut($ix1 - 1)[cix] = ($source).clone();
1039 }
1040 }
1041 };}
1042
1043macro_rules! assign_2d_scalar_range_v {
1044 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1045 unsafe {
1046 for i in 0..($ix2).len() {
1047 let cix = $ix2[i] - 1;
1048 ($sink).row_mut($ix1 - 1)[cix] = ($source)[i].clone();
1049 }
1050 }
1051 };
1052}
1053
1054macro_rules! assign_2d_scalar_range_b {
1055 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1056 unsafe {
1057 for cix in 0..($ix2).len() {
1058 if $ix2[cix] == true {
1059 ($sink).row_mut($ix1 - 1)[cix] = ($source).clone();
1060 }
1061 }
1062 }
1063 };}
1064
1065macro_rules! assign_2d_scalar_range_vb {
1066 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1067 unsafe {
1068 for cix in 0..($ix2).len() {
1069 if $ix2[cix] == true {
1070 ($sink).row_mut($ix1 - 1)[cix] = ($source)[cix].clone();
1071 }
1072 }
1073 }
1074 };}
1075
1076#[macro_export]
1077macro_rules! impl_assign_scalar_range_fxn_s {
1078 ($struct_name:ident, $op:tt, $ix:ty) => {
1079 #[derive(Debug)]
1080 pub struct $struct_name<T, MatA, IxVec> {
1081 pub source: Ref<T>,
1082 pub ixes: (Ref<usize>,Ref<IxVec>),
1083 pub sink: Ref<MatA>,
1084 pub _marker: PhantomData<T>,
1085 }
1086 impl<T, R, C, S: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
1087 where
1088 Ref<naMatrix<T, R, C, S>>: ToValue,
1089 T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
1090 IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
1091 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
1092 naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
1093 {
1094 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
1095 match args {
1096 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
1097 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
1098 let ix1: Ref<usize> = unsafe { arg2.as_unchecked() }.clone();
1099 let ix2: Ref<IxVec> = unsafe { arg3.as_unchecked() }.clone();
1100 let sink: Ref<na::Matrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
1101 Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData }))
1102 }
1103 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
1104 }
1105 }
1106 }
1107 impl<T, R, C, S, IxVec> MechFunctionImpl for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
1108 where
1109 Ref<naMatrix<T, R, C, S>>: ToValue,
1110 T: Scalar + Clone + Debug + Sync + Send + 'static,
1111 IxVec: AsRef<[$ix]> + Debug,
1112 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
1113 {
1114 fn solve(&self) {
1115 unsafe {
1116 let sink = &mut *self.sink.as_mut_ptr();
1117 let source = &*self.source.as_ptr();
1118 let ix1 = (*self.ixes.0.as_ptr());
1119 let ix2 = (*self.ixes.1.as_ptr()).as_ref();
1120 $op!(sink, ix1, ix2, source);
1121 }
1122 }
1123 fn out(&self) -> Value {self.sink.to_value()}
1124 fn to_string(&self) -> String {format!("{:#?}", self)}
1125 }
1126 #[cfg(feature = "compiler")]
1127 impl<T, R, C, S, IxVec> MechFunctionCompiler for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
1128 where
1129 T: CompileConst + ConstElem + AsValueKind,
1130 IxVec: CompileConst + ConstElem + AsNaKind,
1131 naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
1132 {
1133 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1134 let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind(), IxVec::as_na_kind());
1135 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
1136 }
1137 }
1138 };}
1139
1140#[macro_export]
1141macro_rules! impl_assign_scalar_range_fxn_v {
1142 ($struct_name:ident, $op:ident, $ix:ty) => {
1143 #[derive(Debug)]
1144 pub struct $struct_name<T, MatA, MatB, IxVec> {
1145 pub source: Ref<MatB>,
1146 pub ixes: (Ref<usize>,Ref<IxVec>),
1147 pub sink: Ref<MatA>,
1148 pub _marker: PhantomData<T>,
1149 }
1150 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>
1151 where
1152 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
1153 Ref<naMatrix<T, R2, C2, S2>>: ToValue,
1154 T: Debug + Clone + Sync + Send + 'static +
1155 PartialEq + PartialOrd +
1156 CompileConst + ConstElem + AsValueKind,
1157 IxVec: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix]>,
1158 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
1159 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
1160 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
1161 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
1162 {
1163 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
1164 match args {
1165 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
1166 let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
1167 let ix1: Ref<usize> = unsafe { arg2.as_unchecked() }.clone();
1168 let ix2: Ref<IxVec> = unsafe { arg3.as_unchecked() }.clone();
1169 let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
1170 Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData::default() }))
1171 },
1172 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
1173 }
1174 }
1175 }
1176 impl<T, R1, C1, S1, R2, C2, S2, IxVec>
1177 MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
1178 where
1179 Ref<naMatrix<T, R1, C1, S1>>: ToValue,
1180 T: Debug + Clone + Sync + Send + 'static +
1181 PartialEq + PartialOrd,
1182 IxVec: AsRef<[$ix]> + Debug,
1183 R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
1184 R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
1185 {
1186 fn solve(&self) {
1187 unsafe {
1188 let sink = &mut *self.sink.as_mut_ptr();
1189 let source = &*self.source.as_ptr();
1190 let ix1 = (*self.ixes.0.as_ptr());
1191 let ix2 = (*self.ixes.1.as_ptr()).as_ref();
1192 $op!(sink, ix1, ix2, source);
1193 }
1194 }
1195 fn out(&self) -> Value {self.sink.to_value()}
1196 fn to_string(&self) -> String {format!("{:#?}", self)}
1197 }
1198 #[cfg(feature = "compiler")]
1199 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>
1200 where
1201 T: CompileConst + ConstElem + AsValueKind,
1202 IxVec: CompileConst + ConstElem + AsNaKind,
1203 naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
1204 naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
1205 {
1206 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1207 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());
1208 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
1209 }
1210 }
1211 };}
1212
1213impl_assign_scalar_range_fxn_s!(Assign2DSRS, assign_2d_scalar_range, usize);
1214impl_assign_scalar_range_fxn_s!(Assign2DSRB, assign_2d_scalar_range_b, bool);
1215impl_assign_scalar_range_fxn_v!(Assign2DSRV, assign_2d_scalar_range_v, usize);
1216impl_assign_scalar_range_fxn_v!(Assign2DSRVB, assign_2d_scalar_range_vb, bool);
1217
1218fn impl_assign_scalar_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1219 let arg = (sink.clone(), ixes.as_slice(), source.clone());
1220 impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u8, "u8")
1221 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u16, "u16"))
1222 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u32, "u32"))
1223 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u64, "u64"))
1224 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u128, "u128"))
1225 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i8, "i8"))
1226 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i16, "i16"))
1227 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i32, "i32"))
1228 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i64, "i64"))
1229 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i128, "i128"))
1230 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, f32, "f32"))
1231 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, f64, "f64"))
1232 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, R64, "rational"))
1233 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, C64, "complex"))
1234 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, bool, "bool"))
1235 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, String, "string"))
1236
1237 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u8, "u8"))
1238 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u16, "u16"))
1239 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u32, "u32"))
1240 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u64, "u64"))
1241 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u128, "u128"))
1242 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i8, "i8"))
1243 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i16, "i16"))
1244 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i32, "i32"))
1245 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i64, "i64"))
1246 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i128, "i128"))
1247 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, f32, "f32"))
1248 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, f64, "f64"))
1249 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, R64, "rational"))
1250 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, C64, "complex"))
1251 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, bool, "bool"))
1252 .or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, String, "string"))
1253 .map_err(|_| MechError2::new(
1254 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "MatrixAssignScalarRange".to_string() }, None).with_compiler_loc()
1255 )
1256}
1257
1258pub struct MatrixAssignScalarRange {}
1259impl NativeFunctionCompiler for MatrixAssignScalarRange {
1260 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1261 if arguments.len() <= 1 {
1262 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1263 }
1264 let sink: Value = arguments[0].clone();
1265 let source: Value = arguments[1].clone();
1266 let ixes = arguments.clone().split_off(2);
1267 match impl_assign_scalar_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
1268 Ok(fxn) => Ok(fxn),
1269 Err(_) => {
1270 match sink {
1271 Value::MutableReference(sink) => { impl_assign_scalar_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
1272 _ => Err(MechError2::new(
1273 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignScalarRange".to_string() }, None).with_compiler_loc() ),
1274 }
1275 }
1276 }
1277 }
1278}
1279
1280macro_rules! assign_2d_range_range {
1283 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1284 unsafe {
1285 for rix in 0..($ix1).len() {
1286 let r = $ix1[rix] - 1;
1287 for cix in 0..($ix2).len() {
1288 let c = $ix2[cix] - 1;
1289 ($sink)[(r, c)] = ($source).clone();
1290 }
1291 }
1292 }
1293 };}
1294
1295macro_rules! assign_2d_range_range_v {
1296 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1297 unsafe {
1298 for rix in 0..($ix1).len() {
1299 let r = $ix1[rix] - 1;
1300 for cix in 0..($ix2).len() {
1301 let c = $ix2[cix] - 1;
1302 ($sink)[(r, c)] = ($source)[rix * ($ix2).len() + cix].clone();
1303 }
1304 }
1305 }
1306 };}
1307
1308macro_rules! assign_2d_range_range_b {
1309 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1310 unsafe {
1311 for r in 0..($ix1).len() {
1312 if $ix1[r] == true {
1313 for c in 0..($ix2).len() {
1314 if $ix2[c] == true {
1315 ($sink)[(r, c)] = ($source).clone();
1316 }
1317 }
1318 }
1319 }
1320 }
1321 };}
1322
1323macro_rules! assign_2d_range_range_vb {
1324 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1325 unsafe {
1326 for r in 0..($ix1).len() {
1327 if $ix1[r] == true {
1328 for c in 0..($ix2).len() {
1329 if $ix2[c] == true {
1330 ($sink)[(r, c)] = ($source)[r * ($ix2).len() + c].clone();
1331 }
1332 }
1333 }
1334 }
1335 }
1336 };}
1337
1338macro_rules! assign_2d_range_range_bu {
1339 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1340 unsafe {
1341 for r in 0..($ix1).len() {
1342 if $ix1[r] == true {
1343 for cix in 0..($ix2).len() {
1344 let c = $ix2[cix] - 1;
1345 ($sink)[(r, c)] = ($source).clone();
1346 }
1347 }
1348 }
1349 }
1350 };
1351}
1352
1353macro_rules! assign_2d_range_range_vbu {
1354 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1355 unsafe {
1356 let nrows = $sink.nrows();
1357 for cix in 0..($ix2).len() {
1358 let c = $ix2[cix] - 1;
1359 for r in 0..($ix1).len() {
1360 if $ix1[r] {
1361 let offset = r + c * nrows;
1362 ($sink)[(r, c)] = ($source)[offset].clone();
1363 }
1364 }
1365 }
1366 }
1367 };
1368}
1369
1370macro_rules! assign_2d_range_range_ub {
1371 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1372 unsafe {
1373 for r in 0..$ix1.len() {
1374 if $ix1[r] != 0 {
1375 for c in 0..$ix2.len() {
1376 if $ix2[c] {
1377 ($sink)[(r, c)] = $source.clone();
1378 }
1379 }
1380 }
1381 }
1382 }
1383 };
1384}
1385
1386macro_rules! assign_2d_range_range_vub {
1387 ($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
1388 unsafe {
1389 let nrows = $sink.nrows();
1390 for c in 0..$ix2.len() {
1391 if $ix2[c] {
1392 for rix in 0..$ix1.len() {
1393 let r = $ix1[rix] - 1;
1394 let offset = r + c * nrows;
1395 ($sink)[(r, c)] = ($source)[offset].clone();
1396 }
1397 }
1398 }
1399 }
1400 };
1401}
1402
1403#[macro_export]
1404macro_rules! impl_assign_range_range_fxn_s {
1405 ($struct_name:ident, $op:tt, $ix1:ty, $ix2:ty) => {
1406 #[derive(Debug)]
1407 pub struct $struct_name<T, MatA, IxVec1, IxVec2> {
1408 pub source: Ref<T>,
1409 pub ixes: (Ref<IxVec1>,Ref<IxVec2>),
1410 pub sink: Ref<MatA>,
1411 pub _marker: PhantomData<T>,
1412 }
1413 impl<T, R, C, S: 'static, IxVec1: 'static, IxVec2: 'static> MechFunctionFactory for $struct_name<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
1414 where
1415 Ref<naMatrix<T, R, C, S>>: ToValue,
1416 T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
1417 IxVec1: CompileConst + ConstElem + Debug + AsRef<[$ix1]> + AsNaKind,
1418 IxVec2: CompileConst + ConstElem + Debug + AsRef<[$ix2]> + AsNaKind,
1419 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
1420 naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
1421 {
1422 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
1423 match args {
1424 FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
1425 let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
1426 let ix1: Ref<IxVec1> = unsafe { arg2.as_unchecked() }.clone();
1427 let ix2: Ref<IxVec2> = unsafe { arg3.as_unchecked() }.clone();
1428 let sink: Ref<na::Matrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
1429 Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData }))
1430 }
1431 _ => Err(MechError2::new(
1432 IncorrectNumberOfArguments{expected: 3, found: args.len()},
1433 None
1434 ).with_compiler_loc()),
1435 }
1436 }
1437 }
1438 impl<T, R, C, S, IxVec1, IxVec2> MechFunctionImpl for $struct_name<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
1439 where
1440 Ref<naMatrix<T, R, C, S>>: ToValue,
1441 T: Scalar + Clone + Debug + Sync + Send + 'static,
1442 IxVec1: AsRef<[$ix1]> + Debug,
1443 IxVec2: AsRef<[$ix2]> + Debug,
1444 R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
1445 {
1446 fn solve(&self) {
1447 unsafe {
1448 let sink = &mut *self.sink.as_mut_ptr();
1449 let source = &*self.source.as_ptr();
1450 let ix1 = (*self.ixes.0.as_ptr()).as_ref();
1451 let ix2 = (*self.ixes.1.as_ptr()).as_ref();
1452 $op!(sink, ix1, ix2, source);
1453 }
1454 }
1455 fn out(&self) -> Value {self.sink.to_value()}
1456 fn to_string(&self) -> String {format!("{:#?}", self)}
1457 }
1458 #[cfg(feature = "compiler")]
1459 impl<T, R, C, S, IxVec1, IxVec2> MechFunctionCompiler for $struct_name<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
1460 where
1461 T: CompileConst + ConstElem + AsValueKind,
1462 IxVec1: CompileConst + ConstElem + AsNaKind,
1463 IxVec2: CompileConst + ConstElem + AsNaKind,
1464 naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
1465 {
1466 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
1467 let name = format!("{}<{}{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind(), IxVec1::as_na_kind(), IxVec2::as_na_kind());
1468 compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
1469 }
1470 }
1471 };}
1472
1473impl_assign_range_range_fxn_s!(Assign2DRRS, assign_2d_range_range, usize, usize);
1474impl_range_range_fxn_v!(Assign2DRRV, assign_2d_range_range_v, usize, usize);
1475
1476impl_assign_range_range_fxn_s!(Assign2DRRBB, assign_2d_range_range_b, bool, bool);
1477impl_range_range_fxn_v!(Assign2DRRVBB, assign_2d_range_range_vb, bool, bool);
1478
1479impl_assign_range_range_fxn_s!(Assign2DRRBU, assign_2d_range_range_bu, bool, usize);
1480impl_range_range_fxn_v!(Assign2DRRVBU, assign_2d_range_range_vbu, bool, usize);
1481
1482impl_assign_range_range_fxn_s!(Assign2DRRUB, assign_2d_range_range_ub, usize, bool);
1483impl_range_range_fxn_v!(Assign2DRRVUB, assign_2d_range_range_vub, usize, bool);
1484
1485
1486fn impl_assign_range_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1487 let arg = (sink.clone(), ixes.as_slice(), source.clone());
1488 impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u8, "u8")
1489 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u16, "u16"))
1490 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u32, "u32"))
1491 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u64, "u64"))
1492 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u128, "u128"))
1493 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i8, "i8"))
1494 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i16, "i16"))
1495 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i32, "i32"))
1496 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i64, "i64"))
1497 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i128, "i128"))
1498 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, f32, "f32"))
1499 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, f64, "f64"))
1500 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, R64, "rational"))
1501 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, C64, "complex"))
1502 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, bool, "bool"))
1503 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, String, "string"))
1504
1505 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u8, "u8"))
1506 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u16, "u16"))
1507 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u32, "u32"))
1508 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u64, "u64"))
1509 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u128,"u128"))
1510 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i8, "i8"))
1511 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i16, "i16"))
1512 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i32, "i32"))
1513 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i64, "i64"))
1514 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i128,"i128"))
1515 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, f32, "f32"))
1516 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, f64, "f64"))
1517 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, R64, "rational"))
1518 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, C64, "complex"))
1519 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, bool, "bool"))
1520 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, String, "string"))
1521
1522 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_bu, Assign2DRR, arg, f64, "f64"))
1523
1524 .or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_ub, Assign2DRR, arg, f64, "f64"))
1525
1526 .map_err(|_| MechError2::new(
1527 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "matrix/assign-range".to_string() },
1528 None
1529 ).with_compiler_loc()
1530 )
1531}
1532
1533pub struct MatrixAssignRangeRange {}
1534impl NativeFunctionCompiler for MatrixAssignRangeRange {
1535 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1536 if arguments.len() <= 1 {
1537 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1538 }
1539 let sink: Value = arguments[0].clone();
1540 let source: Value = arguments[1].clone();
1541 let ixes = arguments.clone().split_off(2);
1542 match impl_assign_range_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
1543 Ok(fxn) => Ok(fxn),
1544 Err(_) => {
1545 match sink {
1546 Value::MutableReference(sink) => { impl_assign_range_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
1547 _ => Err(MechError2::new(
1548 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-range".to_string() },
1549 None
1550 ).with_compiler_loc()
1551 ),
1552 }
1553 }
1554 }
1555 }
1556}
1557
1558macro_rules! assign_2d_all_range {
1561 ($source:expr, $ix:expr, $sink:expr) => {
1562 for cix in $ix.iter() {
1563 for rix in 0..($sink).nrows() {
1564 ($sink).column_mut(cix - 1)[rix] = ($source).clone();
1565 }
1566 }
1567 };}
1568
1569macro_rules! assign_2d_all_range_b {
1570 ($source:expr, $ix:expr, $sink:expr) => {
1571 for cix in 0..$ix.len() {
1572 for rix in 0..($sink).nrows() {
1573 if $ix[cix] == true {
1574 ($sink).column_mut(cix)[rix] = ($source).clone();
1575 }
1576 }
1577 }
1578 };}
1579
1580macro_rules! assign_2d_all_range_v {
1581 ($source:expr, $ix:expr, $sink:expr) => {
1582 {
1583 let nsrc = $source.nrows();
1584 for (i, &cix) in $ix.iter().enumerate() {
1585 let col_index = cix - 1;
1586 let mut sink_col = $sink.column_mut(col_index);
1587 let src_col = $source.column(i % nsrc); for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
1589 *dst = src.clone();
1590 }
1591 }
1592 }
1593 };}
1594
1595macro_rules! assign_2d_all_range_vb {
1596 ($source:expr, $ix:expr, $sink:expr) => {
1597 {
1598 let mut src_i = 0;
1599 for (i, cix) in (&$ix).iter().enumerate() {
1600 if *cix == true {
1601 let mut sink_col = ($sink).column_mut(i);
1602 let src_col = ($source).column(src_i);
1603 for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
1604 *dst = src.clone();
1605 }
1606 src_i += 1;
1607 }
1608 }
1609 }
1610 };}
1611
1612impl_all_fxn_v!(Set2DARV, assign_2d_all_range_v, usize);
1613impl_set_all_fxn_s!(Set2DARS, assign_2d_all_range, usize);
1614impl_set_all_fxn_s!(Set2DARB, assign_2d_all_range_b, bool);
1615impl_all_fxn_v!(Set2DARVB, assign_2d_all_range_vb, bool);
1616
1617macro_rules! matrix_assign_all_range_fxn {
1618 ($op_fxn_name:tt, $fxn_name:ident) => {
1619 paste::paste! {
1620 fn $op_fxn_name(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1621 let arg = (sink.clone(), ixes.as_slice(), source.clone());
1622 impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u8, "u8")
1623 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u16, "u16"))
1624 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u32, "u32"))
1625 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u64, "u64"))
1626 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u128, "u128"))
1627 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i8, "i8"))
1628 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i16, "i16"))
1629 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i32, "i32"))
1630 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i64, "i64"))
1631 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i128, "i128"))
1632 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, f32, "f32"))
1633 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, f64, "f64"))
1634 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, R64, "rational"))
1635 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, C64, "complex"))
1636 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, bool, "bool"))
1637 .or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, String, "string"))
1638
1639 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u8, "u8"))
1640 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u16, "u16"))
1641 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u32, "u32"))
1642 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u64, "u64"))
1643 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u128,"u128"))
1644 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i8, "i8"))
1645 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i16, "i16"))
1646 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i32, "i32"))
1647 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i64, "i64"))
1648 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i128,"i128"))
1649 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, f32, "f32"))
1650 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, f64, "f64"))
1651 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, R64, "rational"))
1652 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, C64, "complex"))
1653 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, bool, "bool"))
1654 .or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, String, "string"))
1655 .map_err(|_| MechError2::new(
1656 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
1657 None
1658 ).with_compiler_loc()
1659 )
1660 }
1661 }
1662 }
1663}
1664
1665matrix_assign_all_range_fxn!(impl_assign_all_range_fxn, Set2DAR);
1666
1667pub struct MatrixAssignAllRange {}
1668impl NativeFunctionCompiler for MatrixAssignAllRange {
1669 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1670 if arguments.len() <= 1 {
1671 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1672 }
1673 let sink: Value = arguments[0].clone();
1674 let source: Value = arguments[1].clone();
1675 let ixes = arguments.clone().split_off(2);
1676 match impl_assign_all_range_fxn(sink.clone(), source.clone(), ixes.clone()) {
1677 Ok(fxn) => Ok(fxn),
1678 Err(_) => {
1679 match (sink.clone(), ixes.clone(), source.clone()) {
1680 (Value::MutableReference(sink), ixes, Value::MutableReference(source)) => { impl_assign_all_range_fxn(sink.borrow().clone(), source.borrow().clone(), ixes.clone()) },
1681 (sink, ixes, Value::MutableReference(source)) => { impl_assign_all_range_fxn(sink.clone(), source.borrow().clone(), ixes.clone()) },
1682 (Value::MutableReference(sink), ixes, source) => { impl_assign_all_range_fxn(sink.borrow().clone(), source.clone(), ixes.clone()) },
1683 (sink, ixes, source) => Err(MechError2::new(
1684 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
1685 None
1686 ).with_compiler_loc())
1687 }
1688 }
1689 }
1690 }
1691}
1692
1693macro_rules! assign_2d_range_all {
1696 ($source:expr, $ix:expr, $sink:expr) => {
1697 for cix in 0..($sink).ncols() {
1698 for rix in $ix.iter() {
1699 ($sink).column_mut(cix)[rix - 1] = ($source).clone();
1700 }
1701 }
1702 };}
1703
1704macro_rules! assign_2d_range_all_b {
1705 ($source:expr, $ix:expr, $sink:expr) => {
1706 for cix in 0..($sink).ncols() {
1707 for rix in 0..$ix.len() {
1708 if $ix[rix] == true {
1709 ($sink).column_mut(cix)[rix - 1] = ($source).clone();
1710 }
1711 }
1712 }
1713 };}
1714
1715 macro_rules! assign_2d_range_all_v {
1716 ($source:expr, $ix:expr, $sink:expr) => {
1717 {
1718 let nsrc = $source.nrows();
1719 for (i, &rix) in $ix.iter().enumerate() {
1720 let row_index = rix - 1;
1721 let mut sink_row = $sink.row_mut(row_index);
1722 let src_row = $source.row(i % nsrc); for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
1724 *dst = src.clone();
1725 }
1726 }
1727 }
1728 };}
1729
1730macro_rules! assign_2d_range_all_vb {
1731 ($source:expr, $ix:expr, $sink:expr) => {
1732 {
1733 for (i, rix) in ($ix).iter().enumerate() {
1734 if *rix {
1735 let mut sink_row = ($sink).row_mut(i);
1736 let src_row = ($source).row(i);
1737 for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
1738 *dst = src.clone();
1739 }
1740 }
1741 }
1742 }
1743 };
1744}
1745
1746impl_all_fxn_v!(Set2DRAV,assign_2d_range_all_v,usize);
1747impl_set_all_fxn_s!(Set2DRAS,assign_2d_range_all,usize);
1748impl_set_all_fxn_s!(Set2DRAB,assign_2d_range_all_b,bool);
1749impl_all_fxn_v!(Set2DRAVB,assign_2d_range_all_vb,bool);
1750
1751macro_rules! matrix_assign_range_all_fxn {
1752 ($op_fxn_name:tt, $fxn_name:ident) => {
1753 paste::paste! {
1754 fn $op_fxn_name(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1755 let arg = (sink.clone(), ixes.as_slice(), source.clone());
1756 impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u8, "u8")
1757 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u16, "u16"))
1758 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u32, "u32"))
1759 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u64, "u64"))
1760 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u128, "u128"))
1761 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i8, "i8"))
1762 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i16, "i16"))
1763 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i32, "i32"))
1764 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i64, "i64"))
1765 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, f32, "f32"))
1766 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, f64, "f64"))
1767 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, R64, "rational"))
1768 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, C64, "complex"))
1769 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, bool, "bool"))
1770 .or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, String, "string"))
1771
1772 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u8, "u8"))
1773 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u16, "u16"))
1774 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u32, "u32"))
1775 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u64, "u64"))
1776 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u128,"u128"))
1777 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i8, "i8"))
1778 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i16, "i16"))
1779 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i32, "i32"))
1780 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i64, "i64"))
1781 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i128,"i128"))
1782 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, f32, "f32"))
1783 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, f64, "f64"))
1784 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, R64, "rational"))
1785 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, C64, "complex"))
1786 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, bool, "bool"))
1787 .or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, String, "string"))
1788 .map_err(|_| MechError2::new(
1789 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-range-all".to_string() },
1790 None
1791 ).with_compiler_loc()
1792 )
1793 }
1794 }
1795 }
1796}
1797
1798matrix_assign_range_all_fxn!(impl_assign_range_all_fxn, Set2DRA);
1799
1800pub struct MatrixAssignRangeAll {}
1801impl NativeFunctionCompiler for MatrixAssignRangeAll {
1802 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1803 if arguments.len() <= 1 {
1804 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
1805 }
1806 let sink: Value = arguments[0].clone();
1807 let source: Value = arguments[1].clone();
1808 let ixes = arguments.clone().split_off(2);
1809 match impl_assign_range_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
1810 Ok(fxn) => Ok(fxn),
1811 Err(_) => {
1812 match (sink.clone(),ixes.clone(),source.clone()) {
1813 (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { impl_assign_range_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
1814 (sink,ixes,Value::MutableReference(source)) => { impl_assign_range_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
1815 (Value::MutableReference(sink),ixes,source) => { impl_assign_range_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
1816 x => Err(MechError2::new(
1817 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-range-all".to_string() },
1818 None
1819 ).with_compiler_loc()
1820 ),
1821 }
1822 }
1823 }
1824 }
1825}