summaryrefslogtreecommitdiff
path: root/src/operator.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/operator.h')
-rw-r--r--src/operator.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/operator.h b/src/operator.h
new file mode 100644
index 0000000..b4830eb
--- /dev/null
+++ b/src/operator.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <tuple>
+
+#include "concepts.h"
+
+namespace concepts {
+
+template <typename F, typename T, typename... ARGS>
+concept Operator = Arithmetic<T>
+ && requires(F op, T* f_curr, T* f_next, ARGS... args) {
+ F::apply(f_curr, f_next, args...);
+};
+
+template <typename F, typename T>
+concept Functor = Arithmetic<T>
+ && requires(F f, T* f_curr, T output[F::size]) {
+ F::observe(f_curr, output);
+};
+
+}
+
+template <typename F, typename M, typename... ARGS>
+struct Operator {
+ M& mask;
+ std::tuple<ARGS...> args;
+
+ Operator(F, M& m, ARGS&&... args):
+ mask(m),
+ args(std::forward<ARGS&&>(args)...) { }
+
+ template <typename U>
+ requires concepts::Operator<F,U,ARGS...>
+ void operator()(U f_curr[], U f_next[]) {
+ std::apply([](auto... args) { F::apply(args...); },
+ std::tuple_cat(std::make_tuple(f_curr, f_next), args));
+ }
+};
+
+template <typename F, typename M, typename... ARGS>
+Operator(F, M&, ARGS&&... args) -> Operator<F,M,ARGS...>;