use crate::*;
use mech_core::*;
use paste::paste;
use std::ops::Neg;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::ops::Not;
#[cfg(feature = "matrix")]
use mech_core::matrix::Matrix;
#[derive(Debug)]
struct NotS<T> {
pub arg: Ref<T>,
pub out: Ref<T>,
pub _marker: PhantomData<T>,
}
impl<T> MechFunctionFactory for NotS<T>
where
T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static +
CompileConst + ConstElem + AsValueKind +
Not<Output = T>,
Ref<T>: ToValue,
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Unary(out, arg) => {
let arg: Ref<T> = unsafe { arg.as_unchecked() }.clone();
let out: Ref<T> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self {arg, out, _marker: PhantomData::default() }))
},
_ => Err(MechError::new(
IncorrectNumberOfArguments { expected: 1, found: args.len() },
None
).with_compiler_loc()
),
}
}
}
impl<T> MechFunctionImpl for NotS<T>
where
T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static + Not<Output = T>,
Ref<T>: ToValue,
{
fn solve(&self) {
let arg_ptr = self.arg.as_ptr();
let out_ptr = self.out.as_mut_ptr();
unsafe { *out_ptr = !*arg_ptr; }
}
fn out(&self) -> Value { self.out.to_value() }
fn to_string(&self) -> String { format!("{:#?}", self) }
}
#[cfg(feature = "compiler")]
impl<T> MechFunctionCompiler for NotS<T>
where
T: CompileConst + ConstElem + AsValueKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("NotS<{}>", T::as_value_kind());
compile_unop!(name, self.out, self.arg, ctx, FeatureFlag::Builtin(FeatureKind::Not) );
}
}
register_fxn_descriptor!(NotS, bool, "bool");
#[derive(Debug)]
pub struct NotV<T, MatA> {
pub arg: Ref<MatA>,
pub out: Ref<MatA>,
pub _marker: PhantomData<T>,
}
impl<T, MatA> MechFunctionFactory for NotV<T, MatA>
where
T: Debug + Clone + Sync + Send + 'static +
CompileConst + ConstElem + AsValueKind +
Not<Output = T>,
for<'a> &'a MatA: IntoIterator<Item = &'a T>,
for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
MatA: Debug + CompileConst + ConstElem + AsValueKind + 'static,
Ref<MatA>: ToValue
{
fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
match args {
FunctionArgs::Unary(out, arg) => {
let arg: Ref<MatA> = unsafe { arg.as_unchecked() }.clone();
let out: Ref<MatA> = unsafe { out.as_unchecked() }.clone();
Ok(Box::new(Self {arg, out, _marker: PhantomData::default() }))
},
_ => Err(MechError::new(
IncorrectNumberOfArguments { expected: 1, found: args.len() },
None
).with_compiler_loc()
),
}
}
}
impl<T, MatA> MechFunctionImpl for NotV<T, MatA>
where
Ref<MatA>: ToValue,
T: Debug + Clone + Sync + Send + 'static +
CompileConst + ConstElem + AsValueKind +
Not<Output = T>,
for<'a> &'a MatA: IntoIterator<Item = &'a T>,
for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
MatA: Debug,
{
fn solve(&self) {
unsafe {
let sink_ptr = self.out.as_mut_ptr();
let source_ptr = self.arg.as_ptr();
let sink_ref: &mut MatA = &mut *sink_ptr;
let source_ref: &MatA = &*source_ptr;
for (dst, src) in sink_ref.into_iter().zip(source_ref.into_iter()) {
*dst = !src.clone();
}
}
}
fn out(&self) -> Value {self.out.to_value()}
fn to_string(&self) -> String { format!("{:#?}", self) }
}
#[cfg(feature = "compiler")]
impl<T, MatA> MechFunctionCompiler for NotV<T, MatA>
where
T: CompileConst + ConstElem + AsValueKind,
MatA: CompileConst + ConstElem + AsValueKind,
{
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let name = format!("NotV<{}{}>", T::as_value_kind(), MatA::as_value_kind());
compile_unop!(name, self.out, self.arg, ctx, FeatureFlag::Builtin(FeatureKind::Not) );
}
}
fn impl_not_fxn(arg_value: Value) -> MResult<Box<dyn MechFunction>> {
impl_urnop_match_arms!(
Not,
(arg_value),
Bool, bool, "bool";
)
}
impl_mech_urnop_fxn!(LogicNot,impl_not_fxn,"logic/not");