Lumiera  0.pre.03
»edit your freedom«
function.hpp
Go to the documentation of this file.
1 /*
2  FUNCTION.hpp - metaprogramming utilities for transforming function types
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
51 #ifndef LIB_META_FUNCTION_H
52 #define LIB_META_FUNCTION_H
53 
54 #include "lib/meta/typelist.hpp"
55 #include "lib/meta/util.hpp"
56 
57 #include <functional>
58 
59 
60 
61 namespace lib {
62 namespace meta{
63 
64  using std::function;
65 
66 
107  template<typename FUN, typename SEL =void>
108  struct _Fun
109  : std::false_type
110  {
111  using Functor = FUN;
112  };
113 
115  template<typename FUN>
116  struct _Fun<FUN, enable_if<has_FunctionOperator<FUN>> >
117  : _Fun<decltype(&FUN::operator())>
118  {
119  using Functor = FUN;
120  };
121 
123  template<typename RET, typename...ARGS>
124  struct _Fun<RET(ARGS...)>
125  : std::true_type
126  {
127  using Ret = RET;
128  using Args = Types<ARGS...>;
129  using Sig = RET(ARGS...);
130  using Functor = std::function<Sig>;
131  enum { ARITY = sizeof...(ARGS) };
132  };
133 
135  template<typename RET, typename...ARGS>
136  struct _Fun<RET(ARGS...) noexcept>
137  : _Fun<RET(ARGS...)>
138  { };
139 
141  template<typename SIG>
142  struct _Fun<SIG*>
143  : _Fun<SIG>
144  { };
145 
147  template<typename SIG>
148  struct _Fun<SIG&>
149  : _Fun<SIG>
150  { };
151 
153  template<typename SIG>
154  struct _Fun<SIG&&>
155  : _Fun<SIG>
156  { };
157 
159  template<class C, typename RET, typename...ARGS>
160  struct _Fun<RET (C::*) (ARGS...)>
161  : _Fun<RET(ARGS...)>
162  { };
163 
165  template<class C, typename RET, typename...ARGS>
166  struct _Fun<RET (C::*) (ARGS...) noexcept>
167  : _Fun<RET(ARGS...)>
168  { };
169 
173  template<class C, typename RET, typename...ARGS>
174  struct _Fun<RET (C::*) (ARGS...) const>
175  : _Fun<RET(ARGS...)>
176  { };
177 
179  template<class C, typename FUN>
180  struct _Fun<FUN (C::*)>
181  : _Fun<FUN>
182  { };
183 
184 
185 
186 
187 
196  template<typename FUN, typename SIG, bool =_Fun<FUN>()>
197  struct has_Sig
198  : std::is_same<SIG, typename _Fun<FUN>::Sig>
199  { };
200 
202  template<typename FUN, typename X>
203  struct has_Sig<FUN,X, false>
204  : std::false_type
205  { };
206 
212 #define ASSERT_VALID_SIGNATURE(_FUN_, _SIG_) \
213  static_assert (lib::meta::has_Sig<_FUN_, _SIG_>::value, \
214  "Function " STRINGIFY(_FUN_) " unsuitable, expected signature: " STRINGIFY(_SIG_));
215 
216 
217 
226  template<typename SIG, typename FUN>
227  constexpr inline auto
229  {
230  return has_Sig<FUN,SIG>{};
231  }
232 
238 #define ASSERT_MEMBER_FUNCTOR(_EXPR_, _SIG_) \
239  static_assert (lib::meta::isFunMember<_SIG_>(_EXPR_), \
240  "Member " STRINGIFY(_EXPR_) " unsuitable, expect function signature: " STRINGIFY(_SIG_));
241 
242 
243 
244 
245 
246 
248  template<class TAR>
250 
251  namespace {// Helper to inject instance-pointer instead of placeholder...
256  template<class W, class TAR>
257  constexpr inline TAR*
259  {
260  return static_cast<TAR*> (&instance);
261  }
262 
264  template<class W, typename X>
265  constexpr inline X
266  maybeInject (W&, X&& x)
267  {
268  return std::move(x);
269  }
270  }//(End)Helper for lateBindInstance.
271 
281  template<class W, class TUP>
282  constexpr inline auto
283  lateBindInstance (W& instance, TUP&& invocation)
284  {
285  auto splice = [&instance](auto&& ...xs)
286  {
287  return std::tuple{maybeInject (instance, std::move(xs))...};
288  };
289  return std::apply (splice, std::forward<TUP> (invocation));
290  }
291 
292 
293 
294 
295 
296 
297 
305  template<typename RET, typename ARGS>
307 
308 
309  template< typename RET>
310  struct FunctionTypedef<RET, Types<> >
311  {
312  typedef function<RET(void)> Func;
313  typedef RET Sig();
314  };
315 
316 
317  template< typename RET
318  , typename A1
319  >
320  struct FunctionTypedef<RET, Types<A1>>
321  {
322  typedef function<RET(A1)> Func;
323  typedef RET Sig(A1);
324  };
325 
326 
327  template< typename RET
328  , typename A1
329  , typename A2
330  >
331  struct FunctionTypedef<RET, Types<A1,A2>>
332  {
333  typedef function<RET(A1,A2)> Func;
334  typedef RET Sig(A1,A2);
335  };
336 
337 
338  template< typename RET
339  , typename A1
340  , typename A2
341  , typename A3
342  >
343  struct FunctionTypedef<RET, Types<A1,A2,A3>>
344  {
345  typedef function<RET(A1,A2,A3)> Func;
346  typedef RET Sig(A1,A2,A3);
347  };
348 
349 
350  template< typename RET
351  , typename A1
352  , typename A2
353  , typename A3
354  , typename A4
355  >
356  struct FunctionTypedef<RET, Types<A1,A2,A3,A4>>
357  {
358  typedef function<RET(A1,A2,A3,A4)> Func;
359  typedef RET Sig(A1,A2,A3,A4);
360  };
361 
362 
363  template< typename RET
364  , typename A1
365  , typename A2
366  , typename A3
367  , typename A4
368  , typename A5
369  >
370  struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5>>
371  {
372  typedef function<RET(A1,A2,A3,A4,A5)> Func;
373  typedef RET Sig(A1,A2,A3,A4,A5);
374  };
375 
376 
377  template< typename RET
378  , typename A1
379  , typename A2
380  , typename A3
381  , typename A4
382  , typename A5
383  , typename A6
384  >
385  struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6>>
386  {
387  typedef function<RET(A1,A2,A3,A4,A5,A6)> Func;
388  typedef RET Sig(A1,A2,A3,A4,A5,A6);
389  };
390 
391 
392  template< typename RET
393  , typename A1
394  , typename A2
395  , typename A3
396  , typename A4
397  , typename A5
398  , typename A6
399  , typename A7
400  >
401  struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6,A7>>
402  {
403  typedef function<RET(A1,A2,A3,A4,A5,A6,A7)> Func;
404  typedef RET Sig(A1,A2,A3,A4,A5,A6,A7);
405  };
406 
407 
408  template< typename RET
409  , typename A1
410  , typename A2
411  , typename A3
412  , typename A4
413  , typename A5
414  , typename A6
415  , typename A7
416  , typename A8
417  >
418  struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6,A7,A8>>
419  {
420  typedef function<RET(A1,A2,A3,A4,A5,A6,A7,A8)> Func;
421  typedef RET Sig(A1,A2,A3,A4,A5,A6,A7,A8);
422  };
423 
424 
425  template< typename RET
426  , typename A1
427  , typename A2
428  , typename A3
429  , typename A4
430  , typename A5
431  , typename A6
432  , typename A7
433  , typename A8
434  , typename A9
435  >
436  struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6,A7,A8,A9>>
437  {
438  typedef function<RET(A1,A2,A3,A4,A5,A6,A7,A8,A9)> Func;
439  typedef RET Sig(A1,A2,A3,A4,A5,A6,A7,A8,A9);
440  };
441 
442 
443 
444 
445 
446 }} // namespace lib::meta
447 #endif
constexpr auto lateBindInstance(W &instance, TUP &&invocation)
Fix-up the arguments for a member-function invocation, allowing to inject the actual this instance in...
Definition: function.hpp:283
Meta-function to check that some function like entity offers the expected signature.
Definition: function.hpp:197
A template metaprogramming technique for manipulating collections of types.
Simple and lightweight helpers for metaprogramming and type detection.
Helper for uniform access to function signature types.
Definition: function.hpp:108
constexpr auto isFunMember(FUN)
Helper to pick up a member field for verification.
Definition: function.hpp:228
Implementation namespace for support and library code.
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:91
Placeholder marker for a special argument position to be supplied later.
Definition: function.hpp:249
Build function types from given Argument types.
Definition: function.hpp:306
Trait template to detect presence of a simple function call operator.
Definition: meta/util.hpp:196
constexpr X maybeInject(W &, X &&x)
(default case: fall-through)
Definition: function.hpp:266