34 #define ABL_DEFINE_CPP14_OPERATOR_1(name, op) \
35 template <typename T = void> \
37 using argument_type = T; \
38 using result_type = T; \
39 T operator() (const T& a) \
48 template <typename T, typename U> \
49 auto operator() (const T& a) const \
57 #define ABL_DEFINE_CPP14_OPERATOR_2(name, op) \
58 template <typename T = void> \
59 struct name : std::name<T> {}; \
63 template <typename T, typename U> \
64 auto operator() (const T& a, const U& b) const \
73 ABL_DEFINE_CPP14_OPERATOR_2(plus, +)
74 ABL_DEFINE_CPP14_OPERATOR_2(minus, -)
75 ABL_DEFINE_CPP14_OPERATOR_2(multiplies, *)
76 ABL_DEFINE_CPP14_OPERATOR_2(divides, /)
77 ABL_DEFINE_CPP14_OPERATOR_2(modulus, %)
78 ABL_DEFINE_CPP14_OPERATOR_1(negate, -)
81 ABL_DEFINE_CPP14_OPERATOR_2(equal_to, ==)
82 ABL_DEFINE_CPP14_OPERATOR_2(not_equal_to, !=)
83 ABL_DEFINE_CPP14_OPERATOR_2(greater, >)
84 ABL_DEFINE_CPP14_OPERATOR_2(less, <)
85 ABL_DEFINE_CPP14_OPERATOR_2(greater_equal, >=)
86 ABL_DEFINE_CPP14_OPERATOR_2(less_equal, <=)
89 ABL_DEFINE_CPP14_OPERATOR_2(logical_and, &&)
90 ABL_DEFINE_CPP14_OPERATOR_2(logical_or, ||)
91 ABL_DEFINE_CPP14_OPERATOR_1(logical_not, !)
94 ABL_DEFINE_CPP14_OPERATOR_2(bit_and, &)
95 ABL_DEFINE_CPP14_OPERATOR_2(bit_or, |)
96 ABL_DEFINE_CPP14_OPERATOR_2(bit_xor, ^)
97 ABL_DEFINE_CPP14_OPERATOR_1(bit_not, ~)
101 #define ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(body_expr) \
102 decltype(body_expr) { return (body_expr); }
104 template <
class F,
class... Args>
105 inline auto INVOKE(F&& f, Args&&... args)
106 -> ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(
107 std::forward<F>(f)(std::forward<Args>(args)...))
109 template <class Base, class T, class Derived>
110 inline auto INVOKE(T Base::*pmd, Derived&& ref)
111 -> ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(
112 std::forward<Derived>(ref).*pmd)
114 template <class PMD, class Pointer>
115 inline auto INVOKE(PMD pmd, Pointer&& ptr)
116 -> ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(
117 (*
std::forward<Pointer>(ptr)).*pmd)
119 template <class Base, class T, class Derived, class... Args>
120 inline auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args)
121 -> ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(
122 (
std::forward<Derived>(ref).*pmf)(
std::forward<Args>(args)...))
124 template <class PMF, class Pointer, class... Args>
125 inline auto INVOKE(PMF pmf, Pointer&& ptr, Args&&... args)
126 -> ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(
127 ((*
std::forward<Pointer>(ptr)).*pmf)(
std::forward<Args>(args)...))
134 template <class F, class... ArgTypes>
135 auto invoke(F&& f, ArgTypes&&... args)
136 -> ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(
137 detail::INVOKE(
std::forward<F>(f),
std::forward<ArgTypes>(args)...))
139 #undef ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN
C++ amazing templates and reusable implementations awesomeness.