functional.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21 //
22 
27 #pragma once
28 
29 #include <functional>
30 
31 namespace atria {
32 namespace estd {
33 
34 #define ABL_DEFINE_CPP14_OPERATOR_1(name, op) \
35  template <typename T = void> \
36  struct name { \
37  using argument_type = T; \
38  using result_type = T; \
39  T operator() (const T& a) \
40  { \
41  return op a; \
42  } \
43  }; \
44  \
45  template <> \
46  struct name<void> \
47  { \
48  template <typename T, typename U> \
49  auto operator() (const T& a) const \
50  -> decltype(op a) \
51  { \
52  return op a; \
53  } \
54  }; \
55 
56 
57 #define ABL_DEFINE_CPP14_OPERATOR_2(name, op) \
58  template <typename T = void> \
59  struct name : std::name<T> {}; \
60  template <> \
61  struct name<void> \
62  { \
63  template <typename T, typename U> \
64  auto operator() (const T& a, const U& b) const \
65  -> decltype(a op b) \
66  { \
67  return a op b; \
68  } \
69  }; \
70 
71 
72 // Arithmetic
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, -)
79 
80 // Comparison
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, <=)
87 
88 // Logical
89 ABL_DEFINE_CPP14_OPERATOR_2(logical_and, &&)
90 ABL_DEFINE_CPP14_OPERATOR_2(logical_or, ||)
91 ABL_DEFINE_CPP14_OPERATOR_1(logical_not, !)
92 
93 // Bitwise
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, ~)
98 
99 namespace detail {
100 
101 #define ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN(body_expr) \
102  decltype(body_expr) { return (body_expr); }
103 
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)...))
108 
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)
113 
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)
118 
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)...))
123 
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)...))
128 
129 } // namespace detail
130 
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)...))
138 
139 #undef ABL_ESTD_FUNCTIONAL_DECLTYPE_RETURN
140 
141 } // namespace estd
142 } // namespace atria
STL namespace.
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
Fork me on GitHub