siplasplas
A library for C++ reflection and introspection
function.hpp
1 #ifndef SIPLASPLAS_REFLECTION_STATIC_FUNCTION_HPP
2 #define SIPLASPLAS_REFLECTION_STATIC_FUNCTION_HPP
3 
4 namespace cpp
5 {
6 namespace static_reflection
7 {
8 namespace meta
9 {
10 
11 template<typename SourceInfo, typename FunctionType, FunctionType function>
12 class Function;
13 
14 #ifndef SIPLASPLAS_RUNNING_DOXYGEN
15 template<typename SourceInfo_, typename R, typename... Args,
16  R(*function)(Args...)>
17 class Function<SourceInfo_, R(*)(Args...), function>
18 #else
19 
23 class Function
24 #endif // SIPLASPLAS_RUNNING_DOXYGEN
25 {
26 public:
30  using type = R(*)(Args...);
34  using SourceInfo = SourceInfo_;
35 
36  constexpr Function() = default;
37 
43  template<typename... Args_>
44  static constexpr R invoke(Args_&&... args)
45  {
46  return function(std::forward<Args_>(args)...);
47  }
48 
52  static constexpr type get()
53  {
54  return function;
55  }
56 
62  template<typename... Args_>
63  constexpr R operator()(Args_&&... args) const
64  {
65  return invoke(std::forward<Args_>(args)...);
66  }
67 };
68 
69 #ifndef SIPLASPLAS_RUNNING_DOXYGEN
70 template<typename SourceInfo_, typename R, typename Class, typename... Args,
71  R(Class::*method)(Args...) const>
72 class Function<SourceInfo_, R(Class::*)(Args...) const, method>
73 #else
74 
78 class Function
79 #endif // SIPLASPLAS_RUNNING_DOXYGEN
80 {
81 public:
85  using type = R(Class::*)(Args...) const;
89  using class_type = Class;
93  using SourceInfo = SourceInfo_;
94 
95  constexpr Function() = default;
96 
102  template<typename... Args_>
103  static constexpr R invoke(const Class& object, Args_&&... args)
104  {
105  return object.*method(std::forward<Args_>(args)...);
106  }
107 
111  static constexpr type get()
112  {
113  return method;
114  }
115 
121  template<typename... Args_>
122  constexpr R operator()(const Class& object, Args_&&... args) const
123  {
124  return invoke(object, std::forward<Args_>(args)...);
125  }
126 };
127 
128 #ifndef SIPLASPLAS_DOXYGEN_RUNNING
129 template<typename SourceInfo_, typename R, typename Class, typename... Args,
130  R(Class::*method)(Args...)>
131 class Function<SourceInfo_, R(Class::*)(Args...), method>
132 #else
133 
137 class Function
138 #endif // SIPLASPLAS_DOXYGEN_RUNNING
139 {
140 public:
144  using type = R(Class::*)(Args...);
148  using class_type = Class;
152  using SourceInfo = SourceInfo_;
153 
154  constexpr Function() = default;
155 
161  template<typename... Args_>
162  static constexpr R invoke(Class& object, Args_&&... args)
163  {
164  return (object.*method)(std::forward<Args_>(args)...);
165  }
166 
172  template<typename... Args_>
173  static constexpr R invoke(const Class& object, Args_&&... args)
174  {
175  return (object.*method)(std::forward<Args_>(args)...);
176  }
177 
181  static constexpr type get()
182  {
183  return method;
184  }
185 
191  template<typename... Args_>
192  constexpr R operator()(const Class& object, Args_&&... args) const
193  {
194  return invoke(object, std::forward<Args_>(args)...);
195  }
196 
202  template<typename... Args_>
203  constexpr R operator()(Class& object, Args_&&... args) const
204  {
205  return invoke(object, std::forward<Args_>(args)...);
206  }
207 };
208 
209 } // namespace meta
210 
211 namespace codegen
212 {
213 
214 template<typename FunctionType, FunctionType function>
215 class Function :
217  static_reflection::meta::EmptySourceInfo<Function<FunctionType, function>>,
218  FunctionType,
219  function
220  >
221 {};
222 
223 template<typename... Fs>
224 class OverloadedFunction;
225 
226 template<typename Head>
227 class OverloadedFunction<Head> : public Head
228 {};
229 
230 template<typename Head, typename Second, typename... Tail>
231 class OverloadedFunction<Head, Second, Tail...> : public Head, public OverloadedFunction<Second, Tail...>
232 {
233 public:
234  using class_type = typename Head::class_type;
235  using Head::invoke;
236  using Head::operator();
237  using OverloadedFunction<Second, Tail...>::invoke;
238  using OverloadedFunction<Second, Tail...>::operator();
239 };
240 
241 template<typename Method>
242 class BindedMethod
243 {
244 public:
245  BindedMethod(typename Method::class_type& object) :
246  _object{&object}
247  {}
248 
249  template<typename... Args>
250  auto operator()(Args&&... args) -> decltype(Method::invoke(*std::declval<typename Method::class_type*>(), std::forward<Args>(args)...))
251  {
252  return Method::invoke(*_object, std::forward<Args>(args)...);
253  }
254 
255 private:
256  typename Method::class_type* _object;
257 };
258 
259 template<typename Method>
260 class ConstBindedMethod
261 {
262 public:
263  ConstBindedMethod(const typename Method::class_type& object) :
264  _object{&object}
265  {}
266 
267  template<typename... Args>
268  auto operator()(Args&&... args) -> decltype(Method::invoke(*std::declval<const typename Method::class_type*>(), std::forward<Args>(args)...))
269  {
270  return Method::invoke(*_object, std::forward<Args>(args)...);
271  }
272 
273 private:
274  const typename Method::class_type* _object;
275 };
276 
277 } // namespace codegen
278 
288 template<typename FunctionType, FunctionType function>
289 class Function : public codegen::Function<FunctionType, function>
290 {};
291 
292 } // namespace static_reflection
293 } // namespace cpp
294 #endif // SIPLASPLAS_REFLECTION_STATIC_FUNCTION_HPP
static constexpr R invoke(const Class &object, Args_ &&...args)
Invokes the member function with the given object and arguments.
Definition: function.hpp:173
constexpr R operator()(const Class &object, Args_ &&...args) const
Invokes the function with the given object and arguments.
Definition: function.hpp:192
constexpr R operator()(Class &object, Args_ &&...args) const
Invokes the function with the given object and arguments.
Definition: function.hpp:203
Definition: canary_allocator.hpp:7
SourceInfo_ SourceInfo
Source information of the member function. See cpp::static_reflection::meta::SourceInfo.
Definition: function.hpp:152
R(Class::*)(Args...) type
Pointer to member function type.
Definition: function.hpp:144
Stores static reflection information of a non-const member function.
Definition: function.hpp:12
Returns static reflection information of a function.
Definition: function.hpp:289
Stores static reflection information of a given class.
Definition: class.hpp:31
decltype(auto) invoke(Callable &&callable, const ::cpp::SimpleAny< Storages > &...args)
Invokes a callable object with the given type-erased arguments.
Definition: invoke.hpp:214
static constexpr R invoke(Class &object, Args_ &&...args)
Invokes the member function with the given object and arguments.
Definition: function.hpp:162