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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include <iostream>
#include <functional>
#define show(variable) std::cout << #variable << " = " << variable << std::endl;
enum OperatorType {ProductOperator, SumOperator, AndOperator, OrOperator};
template <int, typename> struct ComposeOperator;
template <typename T>
struct ComposeOperator<ProductOperator, T> {
bool operator() (const T& x, const T& y) {return x * y;}
};
template <typename T>
struct ComposeOperator<SumOperator, T> {
bool operator() (const T& x, const T& y) {return x + y;}
};
template <>
struct ComposeOperator<AndOperator, bool> {
bool operator() (bool x, bool y) {return x && y;}
};
template <>
struct ComposeOperator<OrOperator, bool> {
bool operator() (bool x, bool y) {return x || y;}
};
template <int, typename, typename...> struct ComposedFunction;
template <int N, typename RETURN_TYPE, typename FIRST, typename... REST>
struct ComposedFunction<N, RETURN_TYPE, FIRST, REST...> : ComposedFunction<N, RETURN_TYPE, REST...> {
const FIRST function;
using Base = ComposedFunction<N, RETURN_TYPE, REST...>;
ComposedFunction (FIRST first, REST... rest) : Base(rest...), function(first) {}
template <typename... ARGS>
RETURN_TYPE operator() (ARGS&&... args) const {
return ComposeOperator<N, RETURN_TYPE>()(function(std::forward<ARGS>(args)...), Base::operator()(std::forward<ARGS>(args)...));
}
};
template <int N, typename RETURN_TYPE, typename LAST>
struct ComposedFunction<N, RETURN_TYPE, LAST> {
const LAST function;
ComposedFunction (LAST f) : function(f) {}
template <typename... ARGS>
RETURN_TYPE operator() (ARGS&&... args) const {
return function(std::forward<ARGS>(args)...);
}
};
template <int N, typename RETURN_TYPE, typename... ARGS, typename... FUNCTIONS>
std::function<RETURN_TYPE(ARGS...)> composedFunction (FUNCTIONS&&... f) {
return ComposedFunction<N, RETURN_TYPE, FUNCTIONS...> (std::forward<FUNCTIONS>(f)...);
}
int main() {
std::function<bool(int, double)> f = [](int n, double d) {return n + d < 10;};
std::function<bool(int, double)> g = [](int n, double d) {return n - d > 0;};
std::function<bool(int, double)> h = [](int n, double d) {return n * d > 15;};
std::function<bool(int, double)> F = composedFunction<AndOperator, bool, int, double>(f, g, h);
std::function<bool(int, double)> G = composedFunction<OrOperator, bool, int, double>(f, g, h);
std::cout << std::boolalpha;
show (F(6, 3.5)) // true
show (F(6, 1.5)) // false
show (F(3, 6.5)) // false
show (G(6, 1.5)) // true
show (G(3, 6.5)) // true
}
|