Skip to content

Instantly share code, notes, and snippets.

@newlawrence
Last active July 17, 2018 12:19
Show Gist options
  • Save newlawrence/6f6945fba69bb7e9c6881072f28bd854 to your computer and use it in GitHub Desktop.
Save newlawrence/6f6945fba69bb7e9c6881072f28bd854 to your computer and use it in GitHub Desktop.
C++17 generator of Reduce-able Operators
#include <functional>
#include <tuple>
#include <type_traits>
template<typename T, typename U, typename V>
class ReduceOperator {
T _init;
U _apply;
V _chain;
public:
template<typename X, typename Y, typename Z>
constexpr ReduceOperator(X&& init, Y&& apply, Z&& chain) :
_init{std::forward<X>(init)},
_apply{std::forward<Y>(apply)},
_chain{std::forward<Z>(chain)}
{}
template<typename X, typename Y>
class ReduceOperatorImpl {
const ReduceOperator& _op;
const X& _value;
Y _acc;
public:
constexpr ReduceOperatorImpl(const ReduceOperator& op, const X& value) :
_op{op},
_value{value},
_acc{op._init()}
{}
constexpr operator Y() { return _acc; }
template<typename Z>
constexpr ReduceOperatorImpl& operator>(const Z& value) {
_acc = _op._chain(_acc, _op._apply(_value, value));
return *this;
}
template<typename Z>
constexpr ReduceOperatorImpl& operator,(const Z& value) {
_acc = _op._chain(_acc, _op._apply(_value, value));
return *this;
}
};
template<typename X>
friend constexpr auto operator<(const X& value, const ReduceOperator& op) {
return ReduceOperatorImpl<X, decltype(op._init())>{op, value};
}
};
template<typename T, typename U, typename V>
constexpr auto make_reduce_operator(T&& init, U&& apply, V&& chain) {
return ReduceOperator<std::decay_t<T>, std::decay_t<U>, std::decay_t<V>>{
std::forward<T>(init),
std::forward<U>(apply),
std::forward<V>(chain)
};
}
// Proof of concept, <in> operator:
constexpr auto in = make_reduce_operator(
[]() constexpr { return false; },
[](auto&& l, auto&& r) constexpr { return l == r; },
[](auto&& a, auto&& r) constexpr { return a || r; }
);
// Usage:
// 0 <in> 1, 2, 3 // returns: false
// 1 <in> 1, 2, 3 // returns: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment