summaryrefslogtreecommitdiff
path: root/src/operator.h
blob: b4830eb40477404f6723a650388d7c750ce17738 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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...>;