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#[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#[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");