#[macro_use]
use crate::stdlib::*;
use std::marker::PhantomData;
use std::fmt::Debug;
use nalgebra::{
base::{Matrix as naMatrix, Storage, StorageMut},
Dim, Scalar,
};
#[macro_export]
macro_rules! impl_access_fxn_new {
($op:tt, $fxn_name:ident, $arg:expr, $value_kind:ident, $value_string:tt) => {{
let mut res: MResult<_> = Err(MechError::new(
GenericError { msg: "No matching type found".to_string() },
None
));
#[cfg(feature = "row_vector2")]
{
res = res.or_else(|_| $op!($fxn_name, RowVector2, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "row_vector3")]
{
res = res.or_else(|_| $op!($fxn_name, RowVector3, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "row_vector4")]
{
res = res.or_else(|_| $op!($fxn_name, RowVector4, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "vector2")]
{
res = res.or_else(|_| $op!($fxn_name, Vector2, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "vector3")]
{
res = res.or_else(|_| $op!($fxn_name, Vector3, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "vector4")]
{
res = res.or_else(|_| $op!($fxn_name, Vector4, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrix1")]
{
res = res.or_else(|_| $op!($fxn_name, Matrix1, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrix2")]
{
res = res.or_else(|_| $op!($fxn_name, Matrix2, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrix3")]
{
res = res.or_else(|_| $op!($fxn_name, Matrix3, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrix4")]
{
res = res.or_else(|_| $op!($fxn_name, Matrix4, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrix2x3")]
{
res = res.or_else(|_| $op!($fxn_name, Matrix2x3, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrix3x2")]
{
res = res.or_else(|_| $op!($fxn_name, Matrix3x2, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "matrixd")]
{
res = res.or_else(|_| $op!($fxn_name, DMatrix, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "row_vectord")]
{
res = res.or_else(|_| $op!($fxn_name, RowDVector, &$arg, $value_kind, $value_string));
}
#[cfg(feature = "vectord")]
{
res = res.or_else(|_| $op!($fxn_name, DVector, &$arg, $value_kind, $value_string));
}
let &(ref source, ref ixes) = &$arg;
res.map_err(|_| MechError::new(
UnhandledFunctionArgumentIxesMono {
arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()),
fxn_name: stringify!($fxn_name).to_string(),
},
None,
).with_compiler_loc())
}}
}
macro_rules! access_1d {
($source:expr, $ix:expr, $out:expr) => {
unsafe { *$out = (*$source).index(*$ix - 1).clone() }
};}
macro_rules! access_2d {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
*$out = (*$source).index((*$ix1 - 1, *$ix2 - 1)).clone()
}
};}
macro_rules! access_1d_slice {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
for i in 0..(*$ix).len() {
((&mut *$out))[i] = (*$source).index((&(*$ix))[i] - 1).clone();
}
}};}
macro_rules! access_1d_slice_bool {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
let mut j = 0;
let out_len = (*$out).len();
for i in 0..(*$ix).len() {
if (*$ix)[i] == true {
j += 1;
}
}
if j != out_len {
(*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
}
j = 0;
for i in 0..(*$source).len() {
if (*$ix)[i] == true {
(&mut (*$out))[j] = (*$source).index(i).clone();
j += 1;
}
}
}};}
macro_rules! access_1d_slice_bool_v {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
let mut j = 0;
let out_len = (*$out).len();
for i in 0..(*$ix).len() {
if (&(*$ix))[i] == true {
j += 1;
}
}
if j != out_len {
(*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
}
j = 0;
for i in 0..(*$source).len() {
if (&(*$ix))[i] == true {
(&mut (*$out))[j] = (*$source).index(i).clone();
j += 1;
}
}
}};}
macro_rules! access_2d_row_slice_bool {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let scalar_ix = &(*$ix1);
let vec_ix = &(*$ix2);
let mut j = 0;
let out_len = (*$out).len();
for i in 0..vec_ix.len() {
if vec_ix[i] == true {
j += 1;
}
}
if j != out_len {
(*$out).resize_horizontally_mut(j, (&(*$out))[0].clone());
}
j = 0;
for i in 0..vec_ix.len() {
if vec_ix[i] == true {
(&mut (*$out))[j] = (*$source).index((scalar_ix - 1, i)).clone();
j += 1;
}
}
}};}
macro_rules! access_2d_col_slice_bool {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let vec_ix = &(*$ix1);
let scalar_ix = &(*$ix2);
let mut j = 0;
let out_len = (*$out).len();
for i in 0..vec_ix.len() {
if vec_ix[i] == true {
j += 1;
}
}
if j != out_len {
(*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
}
j = 0;
for i in 0..vec_ix.len() {
if vec_ix[i] == true {
(&mut (*$out))[j] = (*$source).index((i, scalar_ix - 1)).clone();
j += 1;
}
}
}};}
macro_rules! access_2d_slice {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let nrows = (*$ix1).len();
let ncols = (*$ix2).len();
let mut out_ix = 0;
for j in 0..ncols {
for i in 0..nrows {
(&mut (*$out))[out_ix] = (*$source).index(((&(*$ix1))[i] - 1, (&(*$ix2))[j] - 1)).clone();
out_ix += 1;
}
}
}};}
macro_rules! access_2d_slice_bool {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let ix1 = &(*$ix1);
let ix2 = &(*$ix2);
let mut j = 0;
let out_len = (*$out).len();
for i in 0..ix1.len() {
if ix1[i] == true {
j += 1;
}
}
if j != (*$out).nrows() {
(*$out).resize_vertically_mut(j, (&(*$out))[0].clone());
}
j = 0;
for k in 0..ix2.len() {
for i in 0..ix1.len() {
if ix1[i] == true {
(&mut (*$out))[j] = (*$source).index((i, ix2[k] - 1)).clone();
j += 1;
}
}
}
}};}
macro_rules! access_2d_slice_bool2 {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let ix1 = &(*$ix1);
let ix2 = &(*$ix2);
let mut j = 0;
let out_len = (*$out).len();
for i in 0..ix2.len() {
if ix2[i] == true {
j += 1;
}
}
if j != (*$out).ncols() {
(*$out).resize_horizontally_mut(j, (& (*$out))[0].clone());
}
j = 0;
for k in 0..ix2.len() {
for i in 0..ix1.len() {
if ix2[k] == true {
(&mut (*$out))[j] = (*$source).index((ix1[i] - 1, k)).clone();
j += 1;
}
}
}
}};}
macro_rules! access_2d_slice_bool_bool {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let ix1 = &(*$ix1);
let ix2 = &(*$ix2);
let mut k = 0;
let mut j = 0;
let out_len = (*$out).len();
for i in 0..ix1.len() {
if ix1[i] == true {
j += 1;
}
}
for i in 0..ix2.len() {
if ix2[i] == true {
k += 1;
}
}
if j != (*$out).nrows() || k != (*$out).ncols() {
(*$out).resize_mut(j, k, (&(*$out))[0].clone());
}
let mut out_ix = 0;
for k in 0..ix2.len() {
for j in 0..ix1.len() {
if ix1[j] == true && ix2[k] == true {
(&mut (*$out))[out_ix] = (*$source).index((j, k)).clone();
out_ix += 1;
}
}
}
}};}
macro_rules! access_2d_slice_all {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
let n_cols = (*$source).ncols();
let n_rows = (*$ix).nrows();
let mut out_ix = 0;
for c in 0..n_cols {
for r in 0..n_rows {
(&mut (*$out))[out_ix] = (*$source).index(((&(*$ix))[r] - 1, c)).clone();
out_ix += 1;
}
}
}};}
macro_rules! access_2d_slice_all_bool {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
let vec_ix = &(*$ix);
let mut j = 0;
let out_len = (*$out).len();
for i in 0..vec_ix.len() {
if vec_ix[i] == true {
j += 1;
}
}
if j != out_len {
(*$out).resize_vertically_mut(j, (&mut (*$out))[0].clone());
}
j = 0;
for i in 0..vec_ix.len() {
for k in 0..(*$source).ncols() {
if vec_ix[i] == true {
(&mut (*$out))[j] = (*$source).index((i, k)).clone();
j += 1;
}
}
}
}};}
macro_rules! access_2d_row_slice {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let ix1 = &(*$ix1);
let ix2 = &(*$ix2);
let out_cols = ix2.nrows();
let mut out_ix = 0;
for c in 0..out_cols {
(&mut (*$out))[out_ix] = (*$source).index((ix1 - 1, ix2[c] - 1)).clone();
out_ix += 1;
}
}};}
macro_rules! access_2d_col_slice {
($source:expr, $ix1:expr, $ix2:expr, $out:expr) => {
unsafe {
let ix1 = &(*$ix1);
let ix2 = &(*$ix2);
let out_rows = ix1.nrows();
let mut out_ix = 0;
for c in 0..out_rows {
(&mut (*$out))[out_ix] = (*$source).index((ix1[c] - 1, ix2 - 1)).clone();
out_ix += 1;
}
}};}
macro_rules! access_col {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
for i in 0..(*$source).nrows() {
(&mut (*$out))[i] = (*$source).index((i, *$ix - 1)).clone();
}
}};}
macro_rules! access_row {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
for i in 0..(*$source).ncols() {
(&mut (*$out))[i] = (*$source).index((*$ix - 1, i)).clone();
}
}};}
macro_rules! access_1d_all {
($source:expr, $ix:expr, $out:expr) => {
unsafe {
for i in 0..(*$source).len() {
(&mut (*$out))[i] = (*$source).index(i).clone();
}
}};}
macro_rules! impl_access_fxn {
($struct_name:ident, $arg_type:ty, $ix_type:ty, $out_type:ty, $op:ident) => {
#[derive(Debug)]
struct $struct_name<T> {
source: Ref<$arg_type>,
ixes: Ref<$ix_type>,
out: Ref<$out_type>,
}
impl<T> MechFunctionFactory for $struct_name<T>
where
T: Debug + Clone + Sync + Send + PartialEq + 'static +
CompileConst + ConstElem + AsValueKind,
Ref<$out_type>: ToValue
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Binary(out, arg1, arg2) => {
let n: Ref<$arg_type> = unsafe{ arg1.as_unchecked().clone() };
let k: Ref<$ix_type> = unsafe{ arg2.as_unchecked().clone() };
let out: Ref<$out_type> = unsafe{ out.as_unchecked().clone() };
Ok(Box::new($struct_name{source: n,ixes: k,out}))
}
_ => Err(MechError::new(IncorrectNumberOfArguments{expected: 2, found: args.len()}, None).with_compiler_loc()),
}
}
}
impl<T> MechFunctionImpl for $struct_name<T>
where
T: Debug + Clone + Sync + Send + PartialEq + 'static,
Ref<$out_type>: ToValue
{
fn solve(&self) {
let source_ptr = self.source.as_ptr();
let ixes_ptr = self.ixes.as_ptr();
let out_ptr = self.out.as_mut_ptr();
$op!(source_ptr,ixes_ptr,out_ptr);
}
fn out(&self) -> Value { self.out.to_value() }
fn to_string(&self) -> String { format!("{:#?}", self) }
}
#[cfg(feature = "compiler")]
impl<T> MechFunctionCompiler for $struct_name<T>
where
T: CompileConst + ConstElem + AsValueKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("{}<{}>", stringify!($struct_name), T::as_value_kind());
compile_binop!(name, self.out, self.source, self.ixes, ctx, FeatureFlag::Builtin(FeatureKind::Access));
}
}};}
macro_rules! impl_access_fxn2 {
($struct_name:ident, $arg_type:ty, $ix1_type:ty, $ix2_type:ty, $out_type:ty, $op:ident) => {
#[derive(Debug)]
struct $struct_name<T> {
source: Ref<$arg_type>,
ix1: Ref<$ix1_type>,
ix2: Ref<$ix2_type>,
out: Ref<$out_type>,
}
impl<T> MechFunctionFactory for $struct_name<T>
where
T: Debug + Clone + Sync + Send + PartialEq + 'static +
CompileConst + ConstElem + AsValueKind,
Ref<$out_type>: ToValue
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Ternary(out, arg1, arg2, arg3) => {
let source: Ref<$arg_type> = unsafe{ arg1.as_unchecked().clone() };
let ix1: Ref<$ix1_type> = unsafe{ arg2.as_unchecked().clone() };
let ix2: Ref<$ix2_type> = unsafe{ arg3.as_unchecked().clone() };
let out: Ref<$out_type> = unsafe{ out.as_unchecked().clone() };
Ok(Box::new($struct_name{source ,ix1, ix2, out}))
}
_ => Err(MechError::new(IncorrectNumberOfArguments{expected: 3, found: args.len()}, None).with_compiler_loc()),
}
}
}
impl<T> MechFunctionImpl for $struct_name<T>
where
T: Debug + Clone + Sync + Send + PartialEq + 'static,
Ref<$out_type>: ToValue
{
fn solve(&self) {
let source_ptr = self.source.as_ptr();
let ix1_ptr = self.ix1.as_ptr();
let ix2_ptr = self.ix2.as_ptr();
let out_ptr = self.out.as_mut_ptr();
$op!(source_ptr,ix1_ptr,ix2_ptr,out_ptr);
}
fn out(&self) -> Value { self.out.to_value() }
fn to_string(&self) -> String { format!("{:#?}", self) }
}
#[cfg(feature = "compiler")]
impl<T> MechFunctionCompiler for $struct_name<T>
where
T: CompileConst + ConstElem + AsValueKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("{}<{}>", stringify!($struct_name), T::as_value_kind());
compile_ternop!(name, self.out, self.source, self.ix1, self.ix2, ctx, FeatureFlag::Builtin(FeatureKind::Access) );
}
}};}
macro_rules! impl_access_fxn_shape {
($name:ident, $ix_type:ty, $out_type:ty, $fxn:ident) => {
paste!{
#[cfg(feature = "matrix1")]
impl_access_fxn!([<$name M1>], Matrix1<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "matrix2")]
impl_access_fxn!([<$name M2>], Matrix2<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "matrix3")]
impl_access_fxn!([<$name M3>], Matrix3<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "matrix4")]
impl_access_fxn!([<$name M4>], Matrix4<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "matrix2x3")]
impl_access_fxn!([<$name M2x3>], Matrix2x3<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "matrix3x2")]
impl_access_fxn!([<$name M3x2>], Matrix3x2<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "matrixd")]
impl_access_fxn!([<$name MD>], DMatrix<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "vector2")]
impl_access_fxn!([<$name V2>], Vector2<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "vector3")]
impl_access_fxn!([<$name V3>], Vector3<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "vector4")]
impl_access_fxn!([<$name V4>], Vector4<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "vectord")]
impl_access_fxn!([<$name VD>], DVector<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "row_vector2")]
impl_access_fxn!([<$name R2>], RowVector2<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "row_vector3")]
impl_access_fxn!([<$name R3>], RowVector3<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "row_vector4")]
impl_access_fxn!([<$name R4>], RowVector4<T>, $ix_type, $out_type, $fxn);
#[cfg(feature = "row_vectord")]
impl_access_fxn!([<$name RD>], RowDVector<T>, $ix_type, $out_type, $fxn);
}
};}
macro_rules! impl_access_fxn_shape2 {
($name:ident, $ix1_type:ty, $ix2_type:ty, $out_type:ty, $fxn:ident) => {
paste!{
#[cfg(feature = "matrix1")]
impl_access_fxn2!([<$name M1>], Matrix1<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "matrix2")]
impl_access_fxn2!([<$name M2>], Matrix2<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "matrix3")]
impl_access_fxn2!([<$name M3>], Matrix3<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "matrix4")]
impl_access_fxn2!([<$name M4>], Matrix4<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "matrix2x3")]
impl_access_fxn2!([<$name M2x3>], Matrix2x3<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "matrix3x2")]
impl_access_fxn2!([<$name M3x2>], Matrix3x2<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "matrixd")]
impl_access_fxn2!([<$name MD>], DMatrix<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "vector2")]
impl_access_fxn2!([<$name V2>], Vector2<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "vector3")]
impl_access_fxn2!([<$name V3>], Vector3<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "vector4")]
impl_access_fxn2!([<$name V4>], Vector4<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "vectord")]
impl_access_fxn2!([<$name VD>], DVector<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "row_vector2")]
impl_access_fxn2!([<$name R2>], RowVector2<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "row_vector3")]
impl_access_fxn2!([<$name R3>], RowVector3<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "row_vector4")]
impl_access_fxn2!([<$name R4>], RowVector4<T>, $ix1_type, $ix2_type, $out_type, $fxn);
#[cfg(feature = "row_vectord")]
impl_access_fxn2!([<$name RD>], RowDVector<T>, $ix1_type, $ix2_type, $out_type, $fxn);
}
};}
impl_access_fxn_shape!(Access1DS, usize, T, access_1d);
impl_access_fxn_shape2!(Access2DSS, usize, usize, T, access_2d);
impl_access_fxn_shape!(Access1DVD, DVector<usize>, DVector<T>, access_1d_slice);
impl_access_fxn_shape!(Access1DVDb, DVector<bool>, DVector<T>, access_1d_slice_bool_v);
impl_access_fxn_shape!(Access1DA, Value, DVector<T>, access_1d_all);
impl_access_fxn_shape!(Access2DAS, usize, DVector<T>, access_col);
#[cfg(feature = "matrix1")]
impl_access_fxn!(Access2DSAM1, Matrix1<T>, usize, Matrix1<T>, access_row);
#[cfg(all(feature = "matrix2", feature = "row_vector2"))]
impl_access_fxn!(Access2DSAM2, Matrix2<T>, usize, RowVector2<T>, access_row);
#[cfg(all(feature = "matrix3", feature = "row_vector3"))]
impl_access_fxn!(Access2DSAM3, Matrix3<T>, usize, RowVector3<T>, access_row);
#[cfg(all(feature = "matrix4", feature = "row_vector4"))]
impl_access_fxn!(Access2DSAM4, Matrix4<T>, usize, RowVector4<T>, access_row);
#[cfg(all(feature = "matrix2x3", feature = "row_vector3"))]
impl_access_fxn!(Access2DSAM2x3, Matrix2x3<T>, usize, RowVector3<T>, access_row);
#[cfg(all(feature = "matrix3x2", feature = "row_vector2"))]
impl_access_fxn!(Access2DSAM3x2, Matrix3x2<T>, usize, RowVector2<T>, access_row);
#[cfg(all(feature = "matrixd", feature = "row_vectord"))]
impl_access_fxn!(Access2DSAMD, DMatrix<T>, usize, RowDVector<T>, access_row);
impl_access_fxn_shape!(Access2DVDA, DVector<usize>, DMatrix<T>, access_2d_slice_all);
impl_access_fxn_shape!(Access2DVDbA, DVector<bool>, DMatrix<T>, access_2d_slice_all_bool);
impl_access_fxn_shape2!(Access2DSVD, usize, DVector<usize>, RowDVector<T>, access_2d_row_slice);
impl_access_fxn_shape2!(Access2DSVDb, usize, DVector<bool>, RowDVector<T>, access_2d_row_slice_bool);
impl_access_fxn_shape2!(Access2DVDS, DVector<usize>, usize, DVector<T>, access_2d_col_slice);
impl_access_fxn_shape2!(Access2DVDbS, DVector<bool>, usize, DVector<T>, access_2d_col_slice_bool);
macro_rules! impl_access_match_arms {
($fxn_name:ident,$macro_name:ident, $arg:expr) => {
paste!{
[<impl_access_ $macro_name _match_arms>]!(
$fxn_name,
$arg,
Bool => MatrixBool, bool, bool::default(), "bool";
I8 => MatrixI8, i8, i8::default(), "i8";
I16 => MatrixI16, i16, i16::default(), "i16";
I32 => MatrixI32, i32, i32::default(), "i32";
I64 => MatrixI64, i64, i64::default(), "i64";
I128 => MatrixI128, i128, i128::default(), "i128";
U8 => MatrixU8, u8, u8::default(), "u8";
U16 => MatrixU16, u16, u16::default(), "u16";
U32 => MatrixU32, u32, u32::default(), "u32";
U64 => MatrixU64, u64, u64::default(), "u64";
U128 => MatrixU128, u128, u128::default(), "u128";
F32 => MatrixF32, f32, f32::default(), "f32";
F64 => MatrixF64, f64, f64::default(), "f64";
String => MatrixString, String, String::default(), "string";
C64 => MatrixC64, C64, C64::default(), "complex";
R64 => MatrixR64, R64, R64::default(), "rational";
)
}
}
}
macro_rules! impl_access_scalar_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
#[cfg(all(feature = $value_string, feature = "row_vector4"))]
(Value::$matrix_kind(Matrix::RowVector4(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name R4>], $target_type, $value_string);
Ok(Box::new([<$fxn_name R4>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector3"))]
(Value::$matrix_kind(Matrix::RowVector3(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name R3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name R3>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector2"))]
(Value::$matrix_kind(Matrix::RowVector2(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name R2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name R2>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vector4"))]
(Value::$matrix_kind(Matrix::Vector4(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name V4>], $target_type, $value_string);
Ok(Box::new([<$fxn_name V4>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vector3"))]
(Value::$matrix_kind(Matrix::Vector3(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name V3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name V3>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vector2"))]
(Value::$matrix_kind(Matrix::Vector2(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name V2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name V2>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name M4>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M4>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name M3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M3>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name M2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M2>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix1"))]
(Value::$matrix_kind(Matrix::Matrix1(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name M1>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M1>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name M2x3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M2x3>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name M3x2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M3x2>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "row_vectord"))]
(Value::$matrix_kind(Matrix::RowDVector(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name RD>], $target_type, $value_string);
Ok(Box::new([<$fxn_name RD>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vectord"))]
(Value::$matrix_kind(Matrix::DVector(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name VD>], $target_type, $value_string);
Ok(Box::new([<$fxn_name VD>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix)]) => {
register_fxn_descriptor_inner!([<$fxn_name MD>], $target_type, $value_string);
Ok(Box::new([<$fxn_name MD>] {source: input.clone(), ixes: ix.clone(), out: Ref::new($default) }))
},
)+
)+
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
}
}
}
}
fn impl_access_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access1DS, scalar, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessScalar {}
impl NativeFunctionCompiler for MatrixAccessScalar {
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 ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_scalar_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! impl_access_scalar_scalar_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
#[cfg(all(feature = $value_string, feature = "row_vector4"))]
(Value::$matrix_kind(Matrix::RowVector4(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name R4>], $target_type, $value_string);
Ok(Box::new([<$fxn_name R4>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector3"))]
(Value::$matrix_kind(Matrix::RowVector3(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name R3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name R3>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector2"))]
(Value::$matrix_kind(Matrix::RowVector2(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name R2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name R2>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vector4"))]
(Value::$matrix_kind(Matrix::Vector4(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name V4>], $target_type, $value_string);
Ok(Box::new([<$fxn_name V4>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vector3"))]
(Value::$matrix_kind(Matrix::Vector3(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name V3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name V3>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vector2"))]
(Value::$matrix_kind(Matrix::Vector2(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name V2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name V2>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name M4>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M4>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name M3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M3>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name M2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M2>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name M2x3>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M2x3>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name M3x2>], $target_type, $value_string);
Ok(Box::new([<$fxn_name M3x2>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "row_vectord"))]
(Value::$matrix_kind(Matrix::RowDVector(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name RD>], $target_type, $value_string);
Ok(Box::new([<$fxn_name RD>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "vectord"))]
(Value::$matrix_kind(Matrix::DVector(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name VD>], $target_type, $value_string);
Ok(Box::new([<$fxn_name VD>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix1),Value::Index(ix2)]) => {
register_fxn_descriptor_inner!([<$fxn_name MD>], $target_type, $value_string);
Ok(Box::new([<$fxn_name MD>] {source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new($default) }))
},
)+
)+
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
}
}
}
}
fn impl_access_scalar_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access2DSS, scalar_scalar, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessScalarScalar {}
impl NativeFunctionCompiler for MatrixAccessScalarScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 2 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_scalar_scalar_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! impl_access_range_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
#[cfg(all(feature = $value_string, feature = "row_vector4", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::RowVector4(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbR4, $target_type, $value_string);
Ok(Box::new(Access1DVDbR4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::RowVector3(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbR3, $target_type, $value_string);
Ok(Box::new(Access1DVDbR3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::RowVector2(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbR2, $target_type, $value_string);
Ok(Box::new(Access1DVDbR2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vectord", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::RowDVector(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbRD, $target_type, $value_string);
Ok(Box::new(Access1DVDbRD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vector4", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Vector4(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbV4, $target_type, $value_string);
Ok(Box::new(Access1DVDbV4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vector3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Vector3(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbV3, $target_type, $value_string);
Ok(Box::new(Access1DVDbV3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vector2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Vector2(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbV2, $target_type, $value_string);
Ok(Box::new(Access1DVDbV2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::DVector(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbVD, $target_type, $value_string);
Ok(Box::new(Access1DVDbVD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbM4, $target_type, $value_string);
Ok(Box::new(Access1DVDbM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbM3, $target_type, $value_string);
Ok(Box::new(Access1DVDbM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbM2, $target_type, $value_string);
Ok(Box::new(Access1DVDbM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix1", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix1(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbM1, $target_type, $value_string);
Ok(Box::new(Access1DVDbM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbM3x2, $target_type, $value_string);
Ok(Box::new(Access1DVDbM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbM2x3, $target_type, $value_string);
Ok(Box::new(Access1DVDbM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDbMD, $target_type, $value_string);
Ok(Box::new(Access1DVDbMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector4"))]
(Value::$matrix_kind(Matrix::RowVector4(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDR4, $target_type, $value_string);
Ok(Box::new(Access1DVDR4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector3"))]
(Value::$matrix_kind(Matrix::RowVector3(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDR3, $target_type, $value_string);
Ok(Box::new(Access1DVDR3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vector2"))]
(Value::$matrix_kind(Matrix::RowVector2(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDR2, $target_type, $value_string);
Ok(Box::new(Access1DVDR2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "row_vectord"))]
(Value::$matrix_kind(Matrix::RowDVector(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDRD, $target_type, $value_string);
Ok(Box::new(Access1DVDRD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vector4"))]
(Value::$matrix_kind(Matrix::Vector4(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDV4, $target_type, $value_string);
Ok(Box::new(Access1DVDV4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vector3"))]
(Value::$matrix_kind(Matrix::Vector3(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDV3, $target_type, $value_string);
Ok(Box::new(Access1DVDV3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vector2"))]
(Value::$matrix_kind(Matrix::Vector2(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDV2, $target_type, $value_string);
Ok(Box::new(Access1DVDV2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "vectord"))]
(Value::$matrix_kind(Matrix::DVector(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDVD, $target_type, $value_string);
Ok(Box::new(Access1DVDVD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDM4, $target_type, $value_string);
Ok(Box::new(Access1DVDM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDM3, $target_type, $value_string);
Ok(Box::new(Access1DVDM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDM2, $target_type, $value_string);
Ok(Box::new(Access1DVDM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix1"))]
(Value::$matrix_kind(Matrix::Matrix1(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDM1, $target_type, $value_string);
Ok(Box::new(Access1DVDM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDM3x2, $target_type, $value_string);
Ok(Box::new(Access1DVDM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDM2x3, $target_type, $value_string);
Ok(Box::new(Access1DVDM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_fxn_descriptor_inner!(Access1DVDMD, $target_type, $value_string);
Ok(Box::new(Access1DVDMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(ix.borrow().len(),$default)) }))
},
)+
)+
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
}
}
}
}
fn impl_access_range_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access1DR, range, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessRange {}
impl NativeFunctionCompiler for MatrixAccessRange {
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 ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_range_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_range_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRange".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! access_2d_range_range_vbb {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut sink_rix = 0;
let mut sink_cix = 0;
for r in 0..($ix1).len() {
if ($ix1)[r] == true {
for c in 0..($ix2).len() {
if ($ix2)[c] == true {
($sink)[(sink_rix, sink_cix)] = ($source)[(r, c)].clone();
sink_cix += 1;
}
}
sink_cix = 0;
sink_rix += 1;
}
}
}
};}
macro_rules! access_2d_range_range_vuu {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut sink_rix = 0;
let mut sink_cix = 0;
for r in 0..($ix1).len() {
let row = ($ix1)[r] - 1;
for c in 0..($ix2).len() {
let col = ($ix2)[c] - 1;
($sink)[(sink_rix, sink_cix)] = ($source)[(row, col)].clone();
sink_cix += 1;
}
sink_cix = 0;
sink_rix += 1;
}
}
};}
macro_rules! access_2d_range_range_vub {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut sink_rix = 0;
let mut sink_cix = 0;
for r in 0..($ix1).len() {
let row = ($ix1)[r] - 1;
for c in 0..($ix2).len() {
if ($ix2)[c] == true {
($sink)[(sink_rix, sink_cix)] = ($source)[(row, c)].clone();
sink_cix += 1;
}
}
sink_cix = 0;
sink_rix += 1;
}
}
};}
macro_rules! access_2d_range_range_vbu {
($sink:expr, $ix1:expr, $ix2:expr, $source:expr) => {
unsafe {
let mut sink_rix = 0;
let mut sink_cix = 0;
for r in 0..($ix1).len() {
if ($ix1)[r] == true {
for c in 0..($ix2).len() {
let col = ($ix2)[c] - 1;
($sink)[(sink_rix, sink_cix)] = ($source)[(r, col)].clone();
sink_cix += 1;
}
sink_cix = 0;
sink_rix += 1;
}
}
}
};}
macro_rules! impl_access_range_range_arms {
($fxn_name:ident, $shape:tt, $arg:expr, $value_kind:ident, $value_string:tt) => {
paste!{
match $arg {
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_assign_srr2!([<$fxn_name VUU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VUU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(ix1.borrow().len(), ix2.borrow().len(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord", feature = "row_vectord", feature = "logical_indexing"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))]) => {
let rows = ix1.borrow().iter().filter(|x| **x).count();
let cols = ix2.borrow().iter().filter(|x| **x).count();
match (cols, rows) {
#[cfg(feature = "matrixd")]
(1, 1) => {
register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(1, 1, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "vectord")]
(1, _) => {
register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DVector::from_element(rows, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "row_vectord")]
(_, 1) => {
register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "matrixd")]
_ => {
register_assign_srr_b2!([<$fxn_name VBB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(rows, cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
}
},
#[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixIndex(Matrix::DVector(ix1)), Value::MatrixBool(Matrix::DVector(ix2))]) => {
let cols = ix2.borrow().iter().filter(|x| **x).count();
let rows = ix1.borrow().len();
match (cols, rows) {
#[cfg(feature = "matrixd")]
(1, 1) => {
register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(1, 1, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "vectord")]
(1, _) => {
register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DVector::from_element(rows, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "row_vectord")]
(_, 1) => {
register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "matrixd")]
_ => {
register_assign_srr_ub2!([<$fxn_name VUB>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VUB>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(rows, cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
}
},
#[cfg(all(feature = $value_string, feature = "vectord", feature = "logical_indexing"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)),[Value::MatrixBool(Matrix::DVector(ix1)), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
let cols = ix2.borrow().len();
let rows = ix1.borrow().iter().filter(|x| **x).count();
match (cols, rows) {
#[cfg(feature = "matrixd")]
(1, 1) => {
register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(1, 1, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "vectord")]
(1, _) => {
register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DVector, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DVector::from_element(rows, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "row_vectord")]
(_, 1) => {
register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, RowDVector, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(feature = "matrixd")]
_ => {
register_assign_srr_bu2!([<$fxn_name VBU>], $value_kind, $value_string, DMatrix, $shape, DVector, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VBU>] { source: source.clone(), ixes: (ix1.clone(), ix2.clone()), sink: Ref::new(DMatrix::from_element(rows, cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
}
}
(src, ix) => Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()},
None).with_compiler_loc()
),
}
}
}
}
impl_range_range_fxn_v!(Access2DRRVBB, access_2d_range_range_vbb, bool, bool);
impl_range_range_fxn_v!(Access2DRRVBU, access_2d_range_range_vbu, bool, usize);
impl_range_range_fxn_v!(Access2DRRVUU, access_2d_range_range_vuu, usize, usize);
impl_range_range_fxn_v!(Access2DRRVUB, access_2d_range_range_vub, usize, bool);
fn matrix_access_range_range_fxn(source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (source.clone(), ixes.as_slice());
impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u8, "u8")
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u16, "u16"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u32, "u32"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u64, "u64"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, u128, "u128"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i8, "i8"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i16, "i16"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i32, "i32"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i64, "i64"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, i128, "i128"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, f32, "f32"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, f64, "f64"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, R64, "rational"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, C64, "complex"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, bool, "bool"))
.or_else(|_| impl_access_fxn_new!(impl_access_range_range_arms, Access2DRR, arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxesMono{
arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()
}, None).with_compiler_loc())
}
pub struct MatrixAccessRangeRange {}
impl NativeFunctionCompiler for MatrixAccessRangeRange {
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 source: Value = arguments[0].clone();
let ixes = arguments.clone().split_off(1);
match matrix_access_range_range_fxn(source.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match source {
Value::MutableReference(source) => { matrix_access_range_range_fxn(source.borrow().clone(), ixes.clone()) },
_ => Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()},
None).with_compiler_loc()
),
}
}
}
}
}
macro_rules! impl_access_all_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access1DAM4, $target_type, $value_string);
Ok(Box::new(Access1DAM4 {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access1DAM3, $target_type, $value_string);
Ok(Box::new(Access1DAM3 {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access1DAM2, $target_type, $value_string);
Ok(Box::new(Access1DAM2 {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access1DAM3x2, $target_type, $value_string);
Ok(Box::new(Access1DAM3x2{source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access1DAM2x3, $target_type, $value_string);
Ok(Box::new(Access1DAM2x3{source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access1DAMD, $target_type, $value_string);
Ok(Box::new(Access1DAMD {source: input.clone(), ixes: Ref::new(Value::IndexAll), out: Ref::new(DVector::from_element(input.borrow().len(),$default)) }))
},
)+
)+
(src, ix) => Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()},
None).with_compiler_loc()
),
}
}
}
}
fn impl_access_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access1DA, all, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessAll {}
impl NativeFunctionCompiler for MatrixAccessAll {
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 ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_all_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAll".to_string()}, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! impl_access_all_scalar_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::IndexAll,Value::Index(ix)]) => {
register_fxn_descriptor_inner!(Access2DASM4, $target_type, $value_string);
Ok(Box::new(Access2DASM4 {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::IndexAll,Value::Index(ix)]) => {
register_fxn_descriptor_inner!(Access2DASM3, $target_type, $value_string);
Ok(Box::new(Access2DASM3 {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::IndexAll,Value::Index(ix)]) => {
register_fxn_descriptor_inner!(Access2DASM2, $target_type, $value_string);
Ok(Box::new(Access2DASM2 {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::IndexAll,Value::Index(ix)]) => {
register_fxn_descriptor_inner!(Access2DASM2x3, $target_type, $value_string);
Ok(Box::new(Access2DASM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::IndexAll,Value::Index(ix)]) => {
register_fxn_descriptor_inner!(Access2DASM3x2, $target_type, $value_string);
Ok(Box::new(Access2DASM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::IndexAll,Value::Index(ix)]) => {
register_fxn_descriptor_inner!(Access2DASMD, $target_type, $value_string);
Ok(Box::new(Access2DASMD {source: input.clone(), ixes: ix.clone(), out: Ref::new(DVector::from_element(input.borrow().nrows(),$default)) }))
},
)+
)+
(src, ix) => Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()},
None).with_compiler_loc()
),
}
}
}
}
fn impl_access_all_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access2DAS, all_scalar, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessAllScalar {}
impl NativeFunctionCompiler for MatrixAccessAllScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 2 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_all_scalar_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_all_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllScalar".to_string()}, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! impl_access_scalar_all_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
#[cfg(all(feature = $value_string, feature = "matrix4", feature = "row_vector4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAM4, $target_type, $value_string);
Ok(Box::new(Access2DSAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector4::from_element($default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3", feature = "row_vector3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAM3, $target_type, $value_string);
Ok(Box::new(Access2DSAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector3::from_element($default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2", feature = "row_vector2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAM2, $target_type, $value_string);
Ok(Box::new(Access2DSAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector2::from_element($default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix1", feature = "matrix1"))]
(Value::$matrix_kind(Matrix::Matrix1(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAM1, $target_type, $value_string);
Ok(Box::new(Access2DSAM1{source: input.clone(), ixes: ix.clone(), out: Ref::new(Matrix1::from_element($default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "row_vector2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAM3x2, $target_type, $value_string);
Ok(Box::new(Access2DSAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector2::from_element($default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "row_vector3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAM2x3, $target_type, $value_string);
Ok(Box::new(Access2DSAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowVector3::from_element($default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "row_vectord"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix),Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DSAMD, $target_type, $value_string);
Ok(Box::new(Access2DSAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(RowDVector::from_element(input.borrow().ncols(),$default)) }))
},
)+
)+
(src, ix) => Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()},
None).with_compiler_loc()
),
}
}
}
}
fn impl_access_scalar_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access2DSA, scalar_all, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessScalarAll {}
impl NativeFunctionCompiler for MatrixAccessScalarAll {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 2 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_scalar_all_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(mat, ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (mat.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarAll".to_string()}, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! assign_2d_all_range_v {
($source:expr, $ix:expr, $sink:expr) => {
{
let mut sink_col_ix = 0;
for i in 0..(*$ix).len() {
let col_ix = $ix[i] - 1;
let mut sink_col = ($sink).column_mut(sink_col_ix);
let src_col = ($source).column(col_ix);
for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
*dst = src.clone();
}
sink_col_ix += 1;
}
}
};}
macro_rules! assign_2d_all_range_vb {
($source:expr, $ix:expr, $sink:expr) => {
{
let mut sink_col_ix = 0;
for i in 0..(*$source).ncols() {
if $ix[i] == true {
let mut sink_col = ($sink).column_mut(sink_col_ix);
let src_col = ($source).column(i);
for (dst, src) in sink_col.iter_mut().zip(src_col.iter()) {
*dst = src.clone();
}
sink_col_ix += 1;
}
}
}
};}
macro_rules! impl_access_all_range_arms {
($fxn_name:ident, $shape:tt, $arg:expr, $value_kind:ident, $value_string:tt) => {
paste!{
match $arg {
#[cfg(all(feature = $value_string, feature = "row_vectord", feature = "vectord"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixIndex(Matrix::DVector(ix))]) if source.borrow().nrows() == 1 => {
register_assign!([<$fxn_name V>], $value_kind, $value_string, RowDVector, $shape, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name V>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(RowDVector::from_element(ix.borrow().len(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixIndex(Matrix::DVector(ix))]) => {
register_assign!([<$fxn_name V>], $value_kind, $value_string, DMatrix, $shape, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name V>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(DMatrix::from_element(source.borrow().nrows(), ix.borrow().len(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(all(feature = $value_string, feature = "row_vectord", feature = "vectord"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) if source.borrow().nrows() == 1 => {
let cols = ix.borrow().iter().filter(|&&b| b).count();
register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, RowDVector, $shape, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VB>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(RowDVector::from_element(cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing", feature = "vectord"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) if ix.borrow().iter().filter(|&&b| b).count() == 1 && source.borrow().nrows() != 1 => {
register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, DVector, $shape, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VB>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(DVector::from_element(source.borrow().nrows(), $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing", feature = "vectord"))]
(Value::[<Matrix $value_kind:camel>](Matrix::$shape(source)), [Value::IndexAll, Value::MatrixBool(Matrix::DVector(ix))]) => {
let cols = ix.borrow().iter().filter(|&&b| b).count();
register_assign_b!([<$fxn_name VB>], $value_kind, $value_string, DMatrix, $shape, DVector);
box_mech_fxn(Ok(Box::new([<$fxn_name VB>]{source: source.clone(), ixes: ix.clone(), sink: Ref::new(DMatrix::from_element(source.borrow().nrows(), cols, $value_kind::default())), _marker: std::marker::PhantomData::default() })))
},
(sink, ix) => {
Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (sink.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string()},
None).with_compiler_loc()
)
}
}
}
}
}
impl_all_fxn_v!(Access2DARV, assign_2d_all_range_v, usize);
impl_all_fxn_v!(Access2DARVB, assign_2d_all_range_vb, bool);
fn matrix_access_all_range_fxn(source: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
let arg = (source.clone(), ixes.as_slice());
impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u8, "u8")
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u16, "u16"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u32, "u32"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u64, "u64"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, u128, "u128"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i8, "i8"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i16, "i16"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i32, "i32"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i64, "i64"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, i128, "i128"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, f32, "f32"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, f64, "f64"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, R64, "rational"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, C64, "complex"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, bool, "bool"))
.or_else(|_| impl_access_fxn_new!(impl_access_all_range_arms, Access2DAR, arg, String, "string"))
.map_err(|_| MechError::new(UnhandledFunctionArgumentIxesMono{
arg: (source.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllRange".to_string()
}, None).with_compiler_loc())
}
pub struct MatrixAccessAllRange {}
impl NativeFunctionCompiler for MatrixAccessAllRange {
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 source: Value = arguments[0].clone();
let ixes = arguments.clone().split_off(1);
match matrix_access_all_range_fxn(source.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match source {
Value::MutableReference(source) => { matrix_access_all_range_fxn(source.borrow().clone(), ixes.clone()) },
x => Err(MechError::new(
UnhandledFunctionArgumentIxesMono{arg: (x.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessAllRange".to_string()},
None).with_compiler_loc()
),
}
}
}
}
}
macro_rules! impl_access_range_all_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
// Vector All
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDAM4, $target_type, $value_string);
Ok(Box::new(Access2DVDAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDAM3, $target_type, $value_string);
Ok(Box::new(Access2DVDAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDAM2, $target_type, $value_string);
Ok(Box::new(Access2DVDAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDAM3x2, $target_type, $value_string);
Ok(Box::new(Access2DVDAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDAM2x3, $target_type, $value_string);
Ok(Box::new(Access2DVDAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDAMD, $target_type, $value_string);
Ok(Box::new(Access2DVDAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDbAM4, $target_type, $value_string);
Ok(Box::new(Access2DVDbAM4{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDbAM3, $target_type, $value_string);
Ok(Box::new(Access2DVDbAM3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDbAM2, $target_type, $value_string);
Ok(Box::new(Access2DVDbAM2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDbAM3x2, $target_type, $value_string);
Ok(Box::new(Access2DVDbAM3x2{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDbAM2x3, $target_type, $value_string);
Ok(Box::new(Access2DVDbAM2x3{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix)), Value::IndexAll]) => {
register_fxn_descriptor_inner!(Access2DVDbAMD, $target_type, $value_string);
Ok(Box::new(Access2DVDbAMD{source: input.clone(), ixes: ix.clone(), out: Ref::new(DMatrix::from_element(ix.borrow().len(),input.borrow().ncols(),$default)) }))
},
)+
)+
(src, ixes) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeAll".to_string()}, None).with_compiler_loc()),
}
}
}
}
fn impl_access_range_all_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access2DRA, range_all, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessRangeAll {}
impl NativeFunctionCompiler for MatrixAccessRangeAll {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 2 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_range_all_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat.clone(),ixes.clone()) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_range_all_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src, ixes) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeAll".to_string()}, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! impl_access_range_scalar_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
// Vector Scalar
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDSM4, $target_type, $value_string);
Ok(Box::new(Access2DVDSM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDSM3, $target_type, $value_string);
Ok(Box::new(Access2DVDSM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDSM2, $target_type, $value_string);
Ok(Box::new(Access2DVDSM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDSM2x3, $target_type, $value_string);
Ok(Box::new(Access2DVDSM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDSM3x2, $target_type, $value_string);
Ok(Box::new(Access2DVDSM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixIndex(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDSMD, $target_type, $value_string);
Ok(Box::new(Access2DVDSMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDbSM4, $target_type, $value_string);
Ok(Box::new(Access2DVDbSM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDbSM3, $target_type, $value_string);
Ok(Box::new(Access2DVDbSM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDbSM2, $target_type, $value_string);
Ok(Box::new(Access2DVDbSM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDbSM2x3, $target_type, $value_string);
Ok(Box::new(Access2DVDbSM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDbSM3x2, $target_type, $value_string);
Ok(Box::new(Access2DVDbSM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::MatrixBool(Matrix::DVector(ix1)), Value::Index(ix2)]) => {
register_fxn_descriptor_inner!(Access2DVDbSMD, $target_type, $value_string);
Ok(Box::new(Access2DVDbSMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(DVector::from_element(ix1.borrow().len(),$default)) }))
},)+
)+
(src, ixes) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{arg: (src.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeRange".to_string()}, None).with_compiler_loc()),
}
}
}
}
fn impl_access_range_scalar_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access2DRS, range_scalar, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessRangeScalar {}
impl NativeFunctionCompiler for MatrixAccessRangeScalar {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 2 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_range_scalar_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat,ixes) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_range_scalar_fxn(lhs.borrow().clone(), rhs_value.clone()) }
(src,ixs) => Err(MechError::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), ixs.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessRangeScalar".to_string() }, None).with_compiler_loc()),
}
}
}
}
}
macro_rules! impl_access_scalar_range_match_arms {
($fxn_name:ident, $arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr, $value_string:tt),+);+ $(;)?) => {
paste!{
match $arg {
$(
$(
// Scalar Vector
#[cfg(all(feature = $value_string, feature = "matrix4"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDM4, $target_type, $value_string);
Ok(Box::new(Access2DSVDM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDM3, $target_type, $value_string);
Ok(Box::new(Access2DSVDM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDM2, $target_type, $value_string);
Ok(Box::new(Access2DSVDM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDM3x2, $target_type, $value_string);
Ok(Box::new(Access2DSVDM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDM2x3, $target_type, $value_string);
Ok(Box::new(Access2DSVDM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix1), Value::MatrixIndex(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDMD, $target_type, $value_string);
Ok(Box::new(Access2DSVDMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix4", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix4(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDbM4, $target_type, $value_string);
Ok(Box::new(Access2DSVDbM4{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDbM3, $target_type, $value_string);
Ok(Box::new(Access2DSVDbM3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDbM2, $target_type, $value_string);
Ok(Box::new(Access2DSVDbM2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix3x2(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDbM3x2, $target_type, $value_string);
Ok(Box::new(Access2DSVDbM3x2{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::Matrix2x3(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDbM2x3, $target_type, $value_string);
Ok(Box::new(Access2DSVDbM2x3{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},
#[cfg(all(feature = $value_string, feature = "matrixd", feature = "logical_indexing"))]
(Value::$matrix_kind(Matrix::DMatrix(input)), [Value::Index(ix1), Value::MatrixBool(Matrix::DVector(ix2))]) => {
register_fxn_descriptor_inner!(Access2DSVDbMD, $target_type, $value_string);
Ok(Box::new(Access2DSVDbMD{source: input.clone(), ix1: ix1.clone(), ix2: ix2.clone(), out: Ref::new(RowDVector::from_element(ix2.borrow().len(),$default)) }))
},)+
)+
(src,ix) => Err(MechError::new(UnhandledFunctionArgumentIxesMono{ arg: (src.kind(), ix.iter().map(|x| x.kind()).collect()), fxn_name: stringify!($fxn_name).to_string() }, None).with_compiler_loc()),
}
}
}
}
fn impl_access_scalar_range_fxn(lhs_value: Value, ixes: Vec<Value>) -> MResult<Box<dyn MechFunction>> {
impl_access_match_arms!(Access2DSR, scalar_range, (lhs_value, ixes.as_slice()))
}
pub struct MatrixAccessScalarRange {}
impl NativeFunctionCompiler for MatrixAccessScalarRange {
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() <= 2 {
return Err(MechError::new(IncorrectNumberOfArguments{expected: 1, found: arguments.len()}, None).with_compiler_loc());
}
let ixes = arguments.clone().split_off(1);
let mat = arguments[0].clone();
match impl_access_scalar_range_fxn(mat.clone(), ixes.clone()) {
Ok(fxn) => Ok(fxn),
Err(_) => {
match (mat.clone(),ixes.clone()) {
(Value::MutableReference(lhs),rhs_value) => { impl_access_scalar_range_fxn(lhs.borrow().clone(), rhs_value.clone()) }
x => Err(MechError::new(UnhandledFunctionArgumentIxesMono{ arg: (mat.kind(), ixes.iter().map(|x| x.kind()).collect()), fxn_name: "MatrixAccessScalarRange".to_string() }, None).with_compiler_loc()),
}
}
}
}
}