mech_logic/
not.rs

1use crate::*;
2use mech_core::*;
3use paste::paste;
4use std::ops::Neg;
5use std::fmt::Debug;
6use std::marker::PhantomData;
7use std::ops::Not;
8#[cfg(feature = "matrix")]
9use mech_core::matrix::Matrix;
10
11// Not ------------------------------------------------------------------------
12
13// NotS -----------------------------------------------------------------------
14
15#[derive(Debug)]
16struct NotS<T> {
17  pub arg: Ref<T>,
18  pub out: Ref<T>,
19  pub _marker: PhantomData<T>,
20}
21impl<T> MechFunctionFactory for NotS<T>
22where
23  T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static + 
24  CompileConst + ConstElem + AsValueKind +
25  Not<Output = T>,
26  Ref<T>: ToValue,
27{
28  fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
29    match args {
30      FunctionArgs::Unary(out, arg) => {
31        let arg: Ref<T> = unsafe { arg.as_unchecked() }.clone();
32        let out: Ref<T> = unsafe { out.as_unchecked() }.clone();
33        Ok(Box::new(Self {arg, out, _marker: PhantomData::default() }))
34      },
35      _ => Err(MechError2::new(
36          IncorrectNumberOfArguments { expected: 1, found: args.len() },
37          None
38        ).with_compiler_loc()
39      ),
40    }
41  }
42}
43impl<T> MechFunctionImpl for NotS<T>
44where
45  T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static + Not<Output = T>,
46  Ref<T>: ToValue,
47{
48  fn solve(&self) {
49    let arg_ptr = self.arg.as_ptr();
50    let out_ptr = self.out.as_mut_ptr();
51    unsafe { *out_ptr = !*arg_ptr; }
52  }
53  fn out(&self) -> Value { self.out.to_value() }
54  fn to_string(&self) -> String { format!("{:#?}", self) }
55}
56#[cfg(feature = "compiler")]
57impl<T> MechFunctionCompiler for NotS<T> 
58where
59  T: CompileConst + ConstElem + AsValueKind,
60{
61  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
62    let name = format!("NotS<{}>", T::as_value_kind());
63    compile_unop!(name, self.out, self.arg, ctx, FeatureFlag::Builtin(FeatureKind::Not) );
64  }
65}
66register_fxn_descriptor!(NotS, bool, "bool");
67
68// NotV -----------------------------------------------------------------------
69
70#[derive(Debug)]
71pub struct NotV<T, MatA> {
72  pub arg: Ref<MatA>,
73  pub out: Ref<MatA>,
74  pub _marker: PhantomData<T>,
75}
76impl<T, MatA> MechFunctionFactory for NotV<T, MatA>
77where
78  T: Debug + Clone + Sync + Send + 'static + 
79  CompileConst + ConstElem + AsValueKind +
80  Not<Output = T>,
81  for<'a> &'a MatA: IntoIterator<Item = &'a T>,
82  for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
83  MatA: Debug + CompileConst + ConstElem + AsValueKind + 'static,
84  Ref<MatA>: ToValue
85{
86  fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
87    match args {
88      FunctionArgs::Unary(out, arg) => {
89        let arg: Ref<MatA> = unsafe { arg.as_unchecked() }.clone();
90        let out: Ref<MatA> = unsafe { out.as_unchecked() }.clone();
91        Ok(Box::new(Self {arg, out, _marker: PhantomData::default() }))
92      },
93      _ => Err(MechError2::new(
94          IncorrectNumberOfArguments { expected: 1, found: args.len() },
95          None
96        ).with_compiler_loc()
97      ),
98    }
99  }
100}
101impl<T, MatA> MechFunctionImpl for NotV<T, MatA>
102where
103  Ref<MatA>: ToValue,
104  T: Debug + Clone + Sync + Send + 'static + 
105  CompileConst + ConstElem + AsValueKind +
106  Not<Output = T>,
107  for<'a> &'a MatA: IntoIterator<Item = &'a T>,
108  for<'a> &'a mut MatA: IntoIterator<Item = &'a mut T>,
109  MatA: Debug,
110{
111  fn solve(&self) {
112    unsafe {
113      let sink_ptr = self.out.as_mut_ptr();
114      let source_ptr = self.arg.as_ptr();
115      let sink_ref: &mut MatA = &mut *sink_ptr;
116      let source_ref: &MatA = &*source_ptr;
117      for (dst, src) in sink_ref.into_iter().zip(source_ref.into_iter()) {
118        *dst = !src.clone();
119      }
120    }
121  }
122  fn out(&self) -> Value {self.out.to_value()}
123  fn to_string(&self) -> String { format!("{:#?}", self) }
124}
125#[cfg(feature = "compiler")]
126impl<T, MatA> MechFunctionCompiler for NotV<T, MatA> 
127where
128  T: CompileConst + ConstElem + AsValueKind,
129  MatA: CompileConst + ConstElem + AsValueKind,
130{
131  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
132    let name = format!("NotV<{}{}>", T::as_value_kind(), MatA::as_value_kind());
133    compile_unop!(name, self.out, self.arg, ctx, FeatureFlag::Builtin(FeatureKind::Not) );
134  }
135}
136
137fn impl_not_fxn(arg_value: Value) -> MResult<Box<dyn MechFunction>> {
138  impl_urnop_match_arms!(
139    Not,
140    (arg_value),
141    Bool, bool, "bool";
142  )
143}
144
145impl_mech_urnop_fxn!(LogicNot,impl_not_fxn,"logic/not");