#[macro_use]
use crate::stdlib::*;
use std::marker::PhantomData;
use std::fmt::Debug;
use nalgebra::{
IsContiguous,
base::{Matrix as naMatrix, Storage, StorageMut},
Dim, Scalar,
};
#[macro_export]
macro_rules! impl_set_match_arms {
($fxn_name:ident,$macro_name:ident, $arg:expr) => {
paste!{
[<impl_set_ $macro_name _match_arms>]!(
$fxn_name,
$arg,
Bool, "bool";
U8, "u8";
U16, "u16";
U32, "u32";
U64, "u64";
U128, "u128";
I8, "i8";
I16, "i16";
I32, "i32";
I64, "i64";
U128, "u128";
F32, "f32";
F64, "f64" ;
String, "string";
C64, "complex";
R64, "rational";
)
}
}
}
#[macro_export]
macro_rules! impl_set_all_fxn_s {
($struct_name:ident, $op:ident, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, IxVec> {
pub source: Ref<T>,
pub ixes: Ref<IxVec>,
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, R1, C1, S1: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Binary(out, arg1, arg2) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let ixes: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
},
_ => Err(MechError::new(
IncorrectNumberOfArguments { expected: 2, found: args.len() },
None
).with_compiler_loc()
),
}
}
}
impl<T, R1, C1, S1, IxVec> MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static,
IxVec: AsRef<[$ix]> + Debug,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink_ptr = &mut *self.sink.as_mut_ptr();
let source_ptr = &*self.source.as_ptr();
let ix_ptr = &(*self.ixes.as_ptr()).as_ref();
$op!(source_ptr,ix_ptr,sink_ptr);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R1, C1, S1, IxVec> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, IxVec>
where
T: CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind(), IxVec::as_na_kind());
compile_binop!(name, self.sink, self.ixes, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
}
}};}
#[macro_export]
macro_rules! assign_1d_scalar {
($source:expr, $ix:expr, $sink:expr) => {
($sink)[$ix - 1] = ($source).clone();
};}
#[macro_export]
macro_rules! assign_1d_scalar_b {
($source:expr, $ix:expr, $sink:expr) => {
if $ix {
for ix in 0..$sink.len() {
$sink[ix] = $source.clone();
}
}
};}
#[macro_export]
macro_rules! assign_1d_scalar_vb {
($source:expr, $ix:expr, $sink:expr) => {
if *$ix {
let len = $sink.len().min($source.len());
for ix in 0..len {
$sink[ix] = $source[ix].clone();
}
}
};}
#[macro_export]
macro_rules! impl_assign_fxn_s {
($struct_name:ident, $op:ident, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA> {
pub source: Ref<T>,
pub ixes: Ref<$ix>,
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, R, C, S: 'static> MechFunctionFactory for $struct_name<T, naMatrix<T, R, C, S>>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static +
CompileConst + ConstElem + AsValueKind,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Binary(out, arg1, arg2) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let ixes: Ref<$ix> = unsafe { arg2.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
},
_ => Err(MechError::new(
IncorrectNumberOfArguments { expected: 2, found: args.len() },
None
).with_compiler_loc()
),
}
}
}
impl<T, R, C, S> MechFunctionImpl for $struct_name<T, naMatrix<T, R, C, S>>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static,
R: Dim,
C: Dim,
S: StorageMut<T, R, C> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let mut sink_ptr = &mut *self.sink.as_mut_ptr();
let ix_val = (*self.ixes.as_ptr()).clone();
let source_val = (*self.source.as_ptr()).clone();
$op!(source_val, ix_val, sink_ptr);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R, C, S> MechFunctionCompiler for $struct_name<T, naMatrix<T, R, C, S>>
where
T: CompileConst + ConstElem + AsValueKind,
naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("{}<{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind());
compile_binop!(name, self.sink, self.ixes, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
}
}};}
impl_assign_fxn_s!(Assign1DS, assign_1d_scalar, usize);
impl_assign_fxn_s!(Assign1DB, assign_1d_scalar_b, bool);
impl_assign_scalar_fxn_v!(Assign1DVB, assign_1d_scalar_vb, bool);
fn impl_assign_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms, Assign1D, arg, String, "string"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u8, "u8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_arms_b, Assign1D, arg, String, "string"))
.map_err(|_| MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
None
).with_compiler_loc()
)
}
pub struct MatrixAssignScalar {}
impl NativeFunctionCompiler for MatrixAssignScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(x) => {
match sink {
Value::MutableReference(sink) => { impl_assign_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
sink => Err(MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
None
).with_compiler_loc()
),
}
}
}
}
}
macro_rules! set_1d_range {
($source:expr, $ix:expr, $sink:expr) => {
unsafe {
for i in 0..($ix).len() {
($sink)[($ix)[i] - 1] = ($source).clone();
}
}
};}
macro_rules! set_1d_range_b {
($source:expr, $ix:expr, $sink:expr) => {
unsafe {
for i in 0..($ix).len() {
if $ix[i] == true {
($sink)[i] = ($source).clone();
}
}
}
};}
macro_rules! set_1d_range_vec {
($source:expr, $ix:expr, $sink:expr) => {
unsafe {
for i in 0..($ix).len() {
($sink)[($ix)[i] - 1] = ($source)[i].clone();
}
}
};}
macro_rules! set_1d_range_vec_b {
($source:expr, $ix:expr, $sink:expr) => {
unsafe {
for i in 0..($ix).len() {
if $ix[i] == true {
($sink)[i] = ($source)[i].clone();
}
}
}};}
impl_set_all_fxn_s!(Assign1DRS,set_1d_range,usize);
impl_set_all_fxn_s!(Assign1DRB,set_1d_range_b,bool);
impl_all_fxn_v!(Assign1DRV,set_1d_range_vec,usize);
impl_all_fxn_v!(Assign1DRVB,set_1d_range_vec_b,bool);
fn impl_assign_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_set_range_arms, Assign1DR, arg, String, "string"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u8, "u8"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u16, "u16"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u32, "u32"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u64, "u64"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, u128, "u128"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i8, "i8"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i16, "i16"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i32, "i32"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i64, "i64"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, i128, "i128"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, f32, "f32"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, f64, "f64"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, R64, "rational"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, C64, "complex"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, bool, "bool"))
.or_else(|_| impl_set_range_arms_b!(Assign1DR, &arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRange".to_string() }, None).with_compiler_loc())
}
pub struct MatrixAssignRange {}
impl NativeFunctionCompiler for MatrixAssignRange {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(x) => {
match (sink.clone(),&ixes,source.clone()) {
(Value::MutableReference(sink),_,Value::MutableReference(source)) => { impl_assign_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
(sink,_,Value::MutableReference(source)) => { impl_assign_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
(Value::MutableReference(sink),_,source) => { impl_assign_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
(sink, ixes, source) => Err(MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRange".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
#[derive(Debug)]
pub struct Set1DAS<T, Sink> {
pub source: Ref<T>,
pub sink: Ref<Sink>,
pub _marker: PhantomData<T>,
}
impl<T, R, C, S> MechFunctionFactory for Set1DAS<T, naMatrix<T, R, C, S>>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Debug + Clone + Sync + Send + PartialEq + 'static +
CompileConst + ConstElem + AsValueKind,
R: Dim,
C: Dim,
S: StorageMut<T, R, C> + Debug + IsContiguous + 'static,
naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Unary(out, arg1) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, _marker: PhantomData::default() }))
},
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 2, found: args.len() }, None).with_compiler_loc())
}
}
}
impl<T, R, C, S> MechFunctionImpl for Set1DAS<T, naMatrix<T, R, C, S>>
where
T: Debug + Clone + Sync + Send + PartialEq + 'static,
R: Dim,
C: Dim,
S: StorageMut<T, R, C> + Debug + IsContiguous,
Ref<naMatrix<T, R, C, S>>: ToValue,
{
fn solve(&self) {
unsafe {
let sink = &mut *self.sink.as_mut_ptr();
let source_val = (*self.source.as_ptr()).clone();
let slice = sink.as_mut_slice();
for elem in slice.iter_mut() {
*elem = source_val.clone();
}
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R, C, S> MechFunctionCompiler for Set1DAS<T, naMatrix<T, R, C, S>>
where
T: CompileConst + ConstElem + AsValueKind,
naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("Set1DAS<{}{}>", T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind());
compile_unop!(name, self.sink, self.source, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
}
}
fn impl_assign_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_arms, Set1DA, arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignAll".to_string() }, None).with_compiler_loc())
}
pub struct MatrixAssignAll {}
impl NativeFunctionCompiler for MatrixAssignAll {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match sink {
Value::MutableReference(sink) => { impl_assign_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
_ => Err(MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignAll".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
#[derive(Debug)]
pub struct Assign2DSSS<T, MatA> {
pub source: Ref<T>,
pub ixes: (Ref<usize>, Ref<usize>),
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, R1, C1, S1: 'static> MechFunctionFactory for Assign2DSSS<T, naMatrix<T, R1, C1, S1>>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static +
CompileConst + ConstElem + AsValueKind,
R1: Dim,
C1: Dim,
S1: StorageMut<T, R1, C1> + Clone + Debug,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let ix1: Ref<usize> = unsafe { arg2.as_unchecked() }.clone();
let ix2: Ref<usize> = unsafe { arg3.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R1, C1, S1>> =
unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self {sink,source,ixes: (ix1, ix2),_marker: PhantomData}))
}
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc()),
}
}
}
impl<T, R1, C1, S1> MechFunctionImpl for Assign2DSSS<T, naMatrix<T, R1, C1, S1>>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static,
R1: Dim,
C1: Dim,
S1: StorageMut<T, R1, C1> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink_ptr = &mut *self.sink.as_mut_ptr();
let source_val = (*self.source.as_ptr()).clone();
let r = (*self.ixes.0.as_ptr()).clone();
let c = (*self.ixes.1.as_ptr()).clone();
sink_ptr[(r - 1, c - 1)] = source_val;
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
impl<T, R1, C1, S1> MechFunctionCompiler for Assign2DSSS<T, naMatrix<T, R1, C1, S1>>
where
T: CompileConst + ConstElem + AsValueKind,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("Assign2DSSS<{}{}>", T::as_value_kind(), naMatrix::<T, R1, C1, S1>::as_na_kind());
compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
}
}
fn impl_assign_scalar_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_scalar_arms, Assign2DSS, arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignScalarScalar".to_string() }, None).with_compiler_loc())
}
pub struct MatrixAssignScalarScalar {}
impl NativeFunctionCompiler for MatrixAssignScalarScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_scalar_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match sink {
Value::MutableReference(sink) => { impl_assign_scalar_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
_ => Err(MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignScalarScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! assign_2d_all_scalar {
($source:expr, $ix:expr, $sink:expr) => {
for i in 0..$sink.nrows() {
($sink).column_mut($ix - 1)[i] = ($source).clone();
}
};}
macro_rules! assign_2d_all_vector {
($source:expr, $ix:expr, $sink:expr) => {
for i in 0..$sink.nrows() {
($sink).column_mut($ix - 1)[i] = ($source)[i].clone();
}
};}
#[macro_export]
macro_rules! impl_assign_scalar_fxn_v {
($struct_name:ident, $op:ident, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, MatB> {
pub source: Ref<MatB>,
pub ixes: Ref<$ix>,
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
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>>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
Ref<naMatrix<T, R2, C2, S2>>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
PartialEq + PartialOrd +
CompileConst + ConstElem + AsValueKind,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Binary(out, arg1, arg2) => {
let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
let ixes: Ref<$ix> = unsafe { arg2.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes, _marker: PhantomData::default() }))
},
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
}
}
}
impl<T, R1, C1, S1, R2, C2, S2>
MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
PartialEq + PartialOrd,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink_ptr = &mut *self.sink.as_mut_ptr();
let source_ptr = &*self.source.as_ptr();
let ix_ptr = &(*self.ixes.as_ptr());
$op!(source_ptr,ix_ptr,sink_ptr);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R1, C1, S1, R2, C2, S2> MechFunctionCompiler for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>>
where
T: CompileConst + ConstElem + AsValueKind,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
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());
compile_binop!(name, self.sink, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::Assign));
}
}
};}
impl_assign_fxn_s!(Assign2DASS, assign_2d_all_scalar, usize);
impl_assign_scalar_fxn_v!(Assign2DASV, assign_2d_all_vector, usize);
fn impl_assign_all_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_all_scalar_arms!(Assign2DAS, &arg, u8, "u8")
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u16, "u16"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u32, "u32"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u64, "u64"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, u128, "u128"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i8, "i8"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i16, "i16"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i32, "i32"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i64, "i64"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, i128, "i128"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, f32, "f32"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, f64, "f64"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, R64, "rational"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, C64, "complex"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, bool, "bool"))
.or_else(|_| impl_assign_all_scalar_arms!(Assign2DAS, &arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc())
}
pub struct MatrixAssignAllScalar {}
impl NativeFunctionCompiler for MatrixAssignAllScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_all_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(x) => {
match sink {
Value::MutableReference(sink) => { impl_assign_all_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
sink => Err(MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! assign_2d_scalar_all_scalar {
($source:expr, $ix:expr, $sink:expr) => {
for i in 0..$sink.ncols() {
($sink).row_mut($ix - 1)[i] = ($source).clone();
}
};}
macro_rules! assign_2d_scalar_all_vector {
($source:expr, $ix:expr, $sink:expr) => {
for i in 0..$sink.ncols() {
($sink).row_mut($ix - 1)[i] = ($source)[i].clone();
}
};}
impl_assign_fxn_s!(Assign2DSAS, assign_2d_scalar_all_scalar, usize);
impl_assign_scalar_fxn_v!(Assign2DSAV, assign_2d_scalar_all_vector, usize);
fn impl_assign_scalar_all_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_scalar_all_arms!(Assign2DSA, &arg, u8, "u8")
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u16, "u16"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u32, "u32"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u64, "u64"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, u128, "u128"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i8, "i8"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i16, "i16"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i32, "i32"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i64, "i64"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, i128, "i128"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, f32, "f32"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, f64, "f64"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, R64, "rational"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, C64, "complex"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, bool, "bool"))
.or_else(|_| impl_assign_scalar_all_arms!(Assign2DSA, &arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc())
}
pub struct MatrixAssignScalarAll {}
impl NativeFunctionCompiler for MatrixAssignScalarAll {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_scalar_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match sink {
Value::MutableReference(sink) => { impl_assign_scalar_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
_ => Err(MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! assign_2d_range_scalar {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut col = ($sink).column_mut($ix2 - 1);
for &rix in ($ix1).iter() {
col[rix - 1] = ($source).clone();
}
}
};
}
macro_rules! assign_2d_range_scalar_v {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut col = ($sink).column_mut($ix2 - 1);
for (i, &rix) in ($ix1).iter().enumerate() {
col[rix - 1] = ($source)[i].clone();
}
}
};
}
macro_rules! assign_2d_range_scalar_b {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut col = ($sink).column_mut($ix2 - 1);
for (rix, &is_selected) in ($ix1).iter().enumerate() {
if is_selected {
col[rix] = ($source).clone();
}
}
}
};
}
macro_rules! assign_2d_range_scalar_vb {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut col = ($sink).column_mut($ix2 - 1);
for (rix, &is_selected) in ($ix1).iter().enumerate() {
if is_selected {
col[rix] = ($source)[rix].clone();
}
}
}
};
}
#[macro_export]
macro_rules! impl_assign_range_scalar_fxn_s {
($struct_name:ident, $op:tt, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, IxVec> {
pub source: Ref<T>,
pub ixes: (Ref<IxVec>, Ref<usize>),
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, R, C, S: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let ix1: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
let ix2: Ref<usize> = unsafe { arg3.as_unchecked() }.clone();
let sink: Ref<na::Matrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData }))
}
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
}
}
}
impl<T, R, C, S, IxVec> MechFunctionImpl for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static,
IxVec: AsRef<[$ix]> + Debug,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink = &mut *self.sink.as_mut_ptr();
let source = &*self.source.as_ptr();
let ix1 = (*self.ixes.0.as_ptr()).as_ref();
let ix2 = (*self.ixes.1.as_ptr());
$op!(sink, ix1, ix2, source);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R, C, S, IxVec> MechFunctionCompiler for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
where
T: CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind(), IxVec::as_na_kind());
compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
}
}
};}
#[macro_export]
macro_rules! impl_assign_range_scalar_fxn_v {
($struct_name:ident, $op:ident, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, MatB, IxVec> {
pub source: Ref<MatB>,
pub ixes: (Ref<IxVec>, Ref<usize>),
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
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>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
Ref<naMatrix<T, R2, C2, S2>>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
PartialEq + PartialOrd +
CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix]>,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
let ix1: Ref<IxVec> = unsafe { arg2.as_unchecked() }.clone();
let ix2: Ref<usize> = unsafe { arg3.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData::default() }))
},
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
}
}
}
impl<T, R1, C1, S1, R2, C2, S2, IxVec>
MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
PartialEq + PartialOrd,
IxVec: AsRef<[$ix]> + Debug,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink = &mut *self.sink.as_mut_ptr();
let source = &*self.source.as_ptr();
let ix1 = (*self.ixes.0.as_ptr()).as_ref();
let ix2 = (*self.ixes.1.as_ptr());
$op!(sink, ix1, ix2, source);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
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>
where
T: CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
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());
compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
}
}
};}
impl_assign_range_scalar_fxn_s!(Assign2DSSMD, assign_2d_range_scalar, usize);
impl_assign_range_scalar_fxn_s!(Assign2DRSS, assign_2d_range_scalar, usize);
impl_assign_range_scalar_fxn_s!(Assign2DRSB, assign_2d_range_scalar_b, bool);
impl_assign_range_scalar_fxn_v!(Assign2DRSV, assign_2d_range_scalar_v, usize);
impl_assign_range_scalar_fxn_v!(Assign2DRSVB, assign_2d_range_scalar_vb, bool);
fn impl_assign_range_scalar_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms, Assign2DRS, arg, String, "string"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u8, "u8"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_scalar_arms_b, Assign2DRS, arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc())
}
pub struct MatrixAssignRangeScalar {}
impl NativeFunctionCompiler for MatrixAssignRangeScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_range_scalar_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match sink {
Value::MutableReference(sink) => { impl_assign_range_scalar_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
_ => Err(MechError::new(UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignRangeScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! assign_2d_scalar_range {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for i in 0..($ix2).len() {
let cix = $ix2[i] - 1;
($sink).row_mut($ix1 - 1)[cix] = ($source).clone();
}
}
};}
macro_rules! assign_2d_scalar_range_v {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for i in 0..($ix2).len() {
let cix = $ix2[i] - 1;
($sink).row_mut($ix1 - 1)[cix] = ($source)[i].clone();
}
}
};
}
macro_rules! assign_2d_scalar_range_b {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for cix in 0..($ix2).len() {
if $ix2[cix] == true {
($sink).row_mut($ix1 - 1)[cix] = ($source).clone();
}
}
}
};}
macro_rules! assign_2d_scalar_range_vb {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for cix in 0..($ix2).len() {
if $ix2[cix] == true {
($sink).row_mut($ix1 - 1)[cix] = ($source)[cix].clone();
}
}
}
};}
#[macro_export]
macro_rules! impl_assign_scalar_range_fxn_s {
($struct_name:ident, $op:tt, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, IxVec> {
pub source: Ref<T>,
pub ixes: (Ref<usize>,Ref<IxVec>),
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, R, C, S: 'static, IxVec: 'static> MechFunctionFactory for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + Debug + AsRef<[$ix]> + AsNaKind,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let ix1: Ref<usize> = unsafe { arg2.as_unchecked() }.clone();
let ix2: Ref<IxVec> = unsafe { arg3.as_unchecked() }.clone();
let sink: Ref<na::Matrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData }))
}
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
}
}
}
impl<T, R, C, S, IxVec> MechFunctionImpl for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static,
IxVec: AsRef<[$ix]> + Debug,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink = &mut *self.sink.as_mut_ptr();
let source = &*self.source.as_ptr();
let ix1 = (*self.ixes.0.as_ptr());
let ix2 = (*self.ixes.1.as_ptr()).as_ref();
$op!(sink, ix1, ix2, source);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R, C, S, IxVec> MechFunctionCompiler for $struct_name<T, na::Matrix<T, R, C, S>, IxVec>
where
T: CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("{}<{}{}{}>", stringify!($struct_name), T::as_value_kind(), naMatrix::<T, R, C, S>::as_na_kind(), IxVec::as_na_kind());
compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
}
}
};}
#[macro_export]
macro_rules! impl_assign_scalar_range_fxn_v {
($struct_name:ident, $op:ident, $ix:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, MatB, IxVec> {
pub source: Ref<MatB>,
pub ixes: (Ref<usize>,Ref<IxVec>),
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
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>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
Ref<naMatrix<T, R2, C2, S2>>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
PartialEq + PartialOrd +
CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind + Debug + AsRef<[$ix]>,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + Debug + AsNaKind,
naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<naMatrix<T, R2, C2, S2>> = unsafe { arg1.as_unchecked() }.clone();
let ix1: Ref<usize> = unsafe { arg2.as_unchecked() }.clone();
let ix2: Ref<IxVec> = unsafe { arg3.as_unchecked() }.clone();
let sink: Ref<naMatrix<T, R1, C1, S1>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData::default() }))
},
_ => Err(MechError::new(IncorrectNumberOfArguments { expected: 3, found: args.len() }, None).with_compiler_loc())
}
}
}
impl<T, R1, C1, S1, R2, C2, S2, IxVec>
MechFunctionImpl for $struct_name<T, naMatrix<T, R1, C1, S1>, naMatrix<T, R2, C2, S2>, IxVec>
where
Ref<naMatrix<T, R1, C1, S1>>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
PartialEq + PartialOrd,
IxVec: AsRef<[$ix]> + Debug,
R1: Dim, C1: Dim, S1: StorageMut<T, R1, C1> + Clone + Debug,
R2: Dim, C2: Dim, S2: Storage<T, R2, C2> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink = &mut *self.sink.as_mut_ptr();
let source = &*self.source.as_ptr();
let ix1 = (*self.ixes.0.as_ptr());
let ix2 = (*self.ixes.1.as_ptr()).as_ref();
$op!(sink, ix1, ix2, source);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
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>
where
T: CompileConst + ConstElem + AsValueKind,
IxVec: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R1, C1, S1>: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R2, C2, S2>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
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());
compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
}
}
};}
impl_assign_scalar_range_fxn_s!(Assign2DSRS, assign_2d_scalar_range, usize);
impl_assign_scalar_range_fxn_s!(Assign2DSRB, assign_2d_scalar_range_b, bool);
impl_assign_scalar_range_fxn_v!(Assign2DSRV, assign_2d_scalar_range_v, usize);
impl_assign_scalar_range_fxn_v!(Assign2DSRVB, assign_2d_scalar_range_vb, bool);
fn impl_assign_scalar_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms, Assign2DSR, arg, String, "string"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u8, "u8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_scalar_range_arms_b, Assign2DSR, arg, String, "string"))
.map_err(|_| MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "MatrixAssignScalarRange".to_string() }, None).with_compiler_loc()
)
}
pub struct MatrixAssignScalarRange {}
impl NativeFunctionCompiler for MatrixAssignScalarRange {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_scalar_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match sink {
Value::MutableReference(sink) => { impl_assign_scalar_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
_ => Err(MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "MatrixAssignScalarRange".to_string() }, None).with_compiler_loc() ),
}
}
}
}
}
macro_rules! assign_2d_range_range {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for rix in 0..($ix1).len() {
let r = $ix1[rix] - 1;
for cix in 0..($ix2).len() {
let c = $ix2[cix] - 1;
($sink)[(r, c)] = ($source).clone();
}
}
}
};}
macro_rules! assign_2d_range_range_v {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for rix in 0..($ix1).len() {
let r = $ix1[rix] - 1;
for cix in 0..($ix2).len() {
let c = $ix2[cix] - 1;
($sink)[(r, c)] = ($source)[rix * ($ix2).len() + cix].clone();
}
}
}
};}
macro_rules! assign_2d_range_range_b {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for r in 0..($ix1).len() {
if $ix1[r] == true {
for c in 0..($ix2).len() {
if $ix2[c] == true {
($sink)[(r, c)] = ($source).clone();
}
}
}
}
}
};}
macro_rules! assign_2d_range_range_vb {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for r in 0..($ix1).len() {
if $ix1[r] == true {
for c in 0..($ix2).len() {
if $ix2[c] == true {
($sink)[(r, c)] = ($source)[r * ($ix2).len() + c].clone();
}
}
}
}
}
};}
macro_rules! assign_2d_range_range_bu {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for r in 0..($ix1).len() {
if $ix1[r] == true {
for cix in 0..($ix2).len() {
let c = $ix2[cix] - 1;
($sink)[(r, c)] = ($source).clone();
}
}
}
}
};
}
macro_rules! assign_2d_range_range_vbu {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let nrows = $sink.nrows();
for cix in 0..($ix2).len() {
let c = $ix2[cix] - 1;
for r in 0..($ix1).len() {
if $ix1[r] {
let offset = r + c * nrows;
($sink)[(r, c)] = ($source)[offset].clone();
}
}
}
}
};
}
macro_rules! assign_2d_range_range_ub {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
for r in 0..$ix1.len() {
if $ix1[r] != 0 {
for c in 0..$ix2.len() {
if $ix2[c] {
($sink)[(r, c)] = $source.clone();
}
}
}
}
}
};
}
macro_rules! assign_2d_range_range_vub {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let nrows = $sink.nrows();
for c in 0..$ix2.len() {
if $ix2[c] {
for rix in 0..$ix1.len() {
let r = $ix1[rix] - 1;
let offset = r + c * nrows;
($sink)[(r, c)] = ($source)[offset].clone();
}
}
}
}
};
}
#[macro_export]
macro_rules! impl_assign_range_range_fxn_s {
($struct_name:ident, $op:tt, $ix1:ty, $ix2:ty) => {
#[derive(Debug)]
pub struct $struct_name<T, MatA, IxVec1, IxVec2> {
pub source: Ref<T>,
pub ixes: (Ref<IxVec1>,Ref<IxVec2>),
pub sink: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, R, C, S: 'static, IxVec1: 'static, IxVec2: 'static> MechFunctionFactory for $struct_name<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static + CompileConst + ConstElem + AsValueKind,
IxVec1: CompileConst + ConstElem + Debug + AsRef<[$ix1]> + AsNaKind,
IxVec2: CompileConst + ConstElem + Debug + AsRef<[$ix2]> + AsNaKind,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
naMatrix<T, R, C, S>: CompileConst + ConstElem + Debug + AsNaKind,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<T> = unsafe { arg1.as_unchecked() }.clone();
let ix1: Ref<IxVec1> = unsafe { arg2.as_unchecked() }.clone();
let ix2: Ref<IxVec2> = unsafe { arg3.as_unchecked() }.clone();
let sink: Ref<na::Matrix<T, R, C, S>> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self { sink, source, ixes: (ix1, ix2), _marker: PhantomData }))
}
_ => Err(MechError::new(
IncorrectNumberOfArguments{expected: 3, found: args.len()},
None
).with_compiler_loc()),
}
}
}
impl<T, R, C, S, IxVec1, IxVec2> MechFunctionImpl for $struct_name<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
where
Ref<naMatrix<T, R, C, S>>: ToValue,
T: Scalar + Clone + Debug + Sync + Send + 'static,
IxVec1: AsRef<[$ix1]> + Debug,
IxVec2: AsRef<[$ix2]> + Debug,
R: Dim, C: Dim, S: StorageMut<T, R, C> + Clone + Debug,
{
fn solve(&self) {
unsafe {
let sink = &mut *self.sink.as_mut_ptr();
let source = &*self.source.as_ptr();
let ix1 = (*self.ixes.0.as_ptr()).as_ref();
let ix2 = (*self.ixes.1.as_ptr()).as_ref();
$op!(sink, ix1, ix2, source);
}
}
fn out(&self) -> Value {self.sink.to_value()}
fn to_string(&self) -> String {format!("{:#?}", self)}
}
#[cfg(feature = "compiler")]
impl<T, R, C, S, IxVec1, IxVec2> MechFunctionCompiler for $struct_name<T, na::Matrix<T, R, C, S>, IxVec1, IxVec2>
where
T: CompileConst + ConstElem + AsValueKind,
IxVec1: CompileConst + ConstElem + AsNaKind,
IxVec2: CompileConst + ConstElem + AsNaKind,
naMatrix<T, R, C, S>: CompileConst + ConstElem + AsNaKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
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());
compile_ternop!(name, self.sink, self.source, self.ixes.0, self.ixes.1, ctx, FeatureFlag::Builtin(FeatureKind::Assign) );
}
}
};}
impl_assign_range_range_fxn_s!(Assign2DRRS, assign_2d_range_range, usize, usize);
impl_range_range_fxn_v!(Assign2DRRV, assign_2d_range_range_v, usize, usize);
impl_assign_range_range_fxn_s!(Assign2DRRBB, assign_2d_range_range_b, bool, bool);
impl_range_range_fxn_v!(Assign2DRRVBB, assign_2d_range_range_vb, bool, bool);
impl_assign_range_range_fxn_s!(Assign2DRRBU, assign_2d_range_range_bu, bool, usize);
impl_range_range_fxn_v!(Assign2DRRVBU, assign_2d_range_range_vbu, bool, usize);
impl_assign_range_range_fxn_s!(Assign2DRRUB, assign_2d_range_range_ub, usize, bool);
impl_range_range_fxn_v!(Assign2DRRVUB, assign_2d_range_range_vub, usize, bool);
fn impl_assign_range_range_fxn(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms, Assign2DRR, arg, String, "string"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u8, "u8"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, u128,"u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, i128,"i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_b, Assign2DRR, arg, String, "string"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_bu, Assign2DRR, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_range_range_arms_ub, Assign2DRR, arg, f64, "f64"))
.map_err(|_| MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "matrix/assign-range".to_string() },
None
).with_compiler_loc()
)
}
pub struct MatrixAssignRangeRange {}
impl NativeFunctionCompiler for MatrixAssignRangeRange {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_range_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match sink {
Value::MutableReference(sink) => { impl_assign_range_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) }
_ => Err(MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-range".to_string() },
None
).with_compiler_loc()
),
}
}
}
}
}
macro_rules! assign_2d_all_range {
($source:expr, $ix:expr, $sink:expr) => {
for cix in $ix.iter() {
for rix in 0..($sink).nrows() {
($sink).column_mut(cix - 1)[rix] = ($source).clone();
}
}
};}
macro_rules! assign_2d_all_range_b {
($source:expr, $ix:expr, $sink:expr) => {
for cix in 0..$ix.len() {
for rix in 0..($sink).nrows() {
if $ix[cix] == true {
($sink).column_mut(cix)[rix] = ($source).clone();
}
}
}
};}
macro_rules! assign_2d_all_range_v {
($source:expr, $ix:expr, $sink:expr) => {
{
let nsrc = $source.nrows();
for (i, &cix) in $ix.iter().enumerate() {
let col_index = cix - 1;
let mut sink_col = $sink.column_mut(col_index);
let src_col = $source.column(i % nsrc); for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
*dst = src.clone();
}
}
}
};}
macro_rules! assign_2d_all_range_vb {
($source:expr, $ix:expr, $sink:expr) => {
{
let mut src_i = 0;
for (i, cix) in (&$ix).iter().enumerate() {
if *cix == true {
let mut sink_col = ($sink).column_mut(i);
let src_col = ($source).column(src_i);
for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
*dst = src.clone();
}
src_i += 1;
}
}
}
};}
impl_all_fxn_v!(Set2DARV, assign_2d_all_range_v, usize);
impl_set_all_fxn_s!(Set2DARS, assign_2d_all_range, usize);
impl_set_all_fxn_s!(Set2DARB, assign_2d_all_range_b, bool);
impl_all_fxn_v!(Set2DARVB, assign_2d_all_range_vb, bool);
macro_rules! matrix_assign_all_range_fxn {
($op_fxn_name:tt, $fxn_name:ident) => {
paste::paste! {
fn $op_fxn_name(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, i128, "i128"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_assign_all_range_arms, $fxn_name, arg, String, "string"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u8, "u8"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u16, "u16"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u32, "u32"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u64, "u64"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, u128,"u128"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i8, "i8"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i16, "i16"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i32, "i32"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i64, "i64"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, i128,"i128"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, f32, "f32"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, f64, "f64"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, R64, "rational"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, C64, "complex"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, bool, "bool"))
.or_else(|_| impl_set_all_range_arms_b!($fxn_name, &arg, String, "string"))
.map_err(|_| MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
None
).with_compiler_loc()
)
}
}
}
}
matrix_assign_all_range_fxn!(impl_assign_all_range_fxn, Set2DAR);
pub struct MatrixAssignAllRange {}
impl NativeFunctionCompiler for MatrixAssignAllRange {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_all_range_fxn(sink.clone(), source.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (sink.clone(), ixes.clone(), source.clone()) {
(Value::MutableReference(sink), ixes, Value::MutableReference(source)) => { impl_assign_all_range_fxn(sink.borrow().clone(), source.borrow().clone(), ixes.clone()) },
(sink, ixes, Value::MutableReference(source)) => { impl_assign_all_range_fxn(sink.clone(), source.borrow().clone(), ixes.clone()) },
(Value::MutableReference(sink), ixes, source) => { impl_assign_all_range_fxn(sink.borrow().clone(), source.clone(), ixes.clone()) },
(sink, ixes, source) => Err(MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-scalar".to_string() },
None
).with_compiler_loc())
}
}
}
}
}
macro_rules! assign_2d_range_all {
($source:expr, $ix:expr, $sink:expr) => {
for cix in 0..($sink).ncols() {
for rix in $ix.iter() {
($sink).column_mut(cix)[rix - 1] = ($source).clone();
}
}
};}
macro_rules! assign_2d_range_all_b {
($source:expr, $ix:expr, $sink:expr) => {
for cix in 0..($sink).ncols() {
for rix in 0..$ix.len() {
if $ix[rix] == true {
($sink).column_mut(cix)[rix - 1] = ($source).clone();
}
}
}
};}
macro_rules! assign_2d_range_all_v {
($source:expr, $ix:expr, $sink:expr) => {
{
let nsrc = $source.nrows();
for (i, &rix) in $ix.iter().enumerate() {
let row_index = rix - 1;
let mut sink_row = $sink.row_mut(row_index);
let src_row = $source.row(i % nsrc); for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
*dst = src.clone();
}
}
}
};}
macro_rules! assign_2d_range_all_vb {
($source:expr, $ix:expr, $sink:expr) => {
{
for (i, rix) in ($ix).iter().enumerate() {
if *rix {
let mut sink_row = ($sink).row_mut(i);
let src_row = ($source).row(i);
for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
*dst = src.clone();
}
}
}
}
};
}
impl_all_fxn_v!(Set2DRAV,assign_2d_range_all_v,usize);
impl_set_all_fxn_s!(Set2DRAS,assign_2d_range_all,usize);
impl_set_all_fxn_s!(Set2DRAB,assign_2d_range_all_b,bool);
impl_all_fxn_v!(Set2DRAVB,assign_2d_range_all_vb,bool);
macro_rules! matrix_assign_range_all_fxn {
($op_fxn_name:tt, $fxn_name:ident) => {
paste::paste! {
fn $op_fxn_name(sink: Value, source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (sink.clone(), ixes.as_slice(), source.clone());
impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u8, "u8")
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u16, "u16"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u32, "u32"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u64, "u64"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, u128, "u128"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i8, "i8"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i16, "i16"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i32, "i32"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, i64, "i64"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, f32, "f32"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, f64, "f64"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, R64, "rational"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, C64, "complex"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, bool, "bool"))
.or_else(|_| impl_assign_fxn!(impl_set_range_all_arms, $fxn_name, arg, String, "string"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u8, "u8"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u16, "u16"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u32, "u32"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u64, "u64"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, u128,"u128"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i8, "i8"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i16, "i16"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i32, "i32"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i64, "i64"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, i128,"i128"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, f32, "f32"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, f64, "f64"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, R64, "rational"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, C64, "complex"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, bool, "bool"))
.or_else(|_| impl_set_range_all_arms_b!($fxn_name, &arg, String, "string"))
.map_err(|_| MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-range-all".to_string() },
None
).with_compiler_loc()
)
}
}
}
}
matrix_assign_range_all_fxn!(impl_assign_range_all_fxn, Set2DRA);
pub struct MatrixAssignRangeAll {}
impl NativeFunctionCompiler for MatrixAssignRangeAll {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 1 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let sink: Value = arguments[0].clone();
let source: Value = arguments[1].clone();
let ixes = arguments.clone().split_off(2);
match impl_assign_range_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (sink.clone(),ixes.clone(),source.clone()) {
(Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { impl_assign_range_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
(sink,ixes,Value::MutableReference(source)) => { impl_assign_range_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
(Value::MutableReference(sink),ixes,source) => { impl_assign_range_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
x => Err(MechError::new(
UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|v| v.kind()).collect::<Vec<_>>(), source.kind()), fxn_name: "matrix/assign-range-all".to_string() },
None
).with_compiler_loc()
),
}
}
}
}
}