2009-06-16 11:39:36 +02:00
|
|
|
/*
|
|
|
|
|
FUNCTION.hpp - metaprogramming utilities for transforming function types
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2009, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
2010-12-17 23:28:49 +01:00
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @file function.hpp
|
|
|
|
|
** Metaprogramming tools for transforming functor types.
|
|
|
|
|
** Sometimes it is necessary to build and remould a function signature, e.g. for
|
|
|
|
|
** creating a functor or a closure based on an existing function of function pointer.
|
|
|
|
|
** This is a core task of functional programming, but sadly C++ in its current shape
|
|
|
|
|
** is still lacking in this area. (C++0X will significantly improve this situation).
|
|
|
|
|
** As an \em pragmatic fix, we define here a collection of templates, specialising
|
|
|
|
|
** them in a very repetitive way for up to 9 function arguments. Doing so enables
|
|
|
|
|
** us to capture a function, access the return type and argument types as a typelist,
|
|
|
|
|
** eventually to manipulate them and re-build a different signature, or to create
|
|
|
|
|
** specifically tailored bindings.
|
|
|
|
|
**
|
|
|
|
|
** If the following code makes you feel like vomiting, please look away,
|
2016-03-25 19:58:09 +01:00
|
|
|
** and rest assured: you aren't alone.
|
|
|
|
|
**
|
|
|
|
|
** @todo rework to use variadic templates and integrage support for lambdas //////////////////////////////////////TICKET #994
|
|
|
|
|
**
|
2009-06-16 11:39:36 +02:00
|
|
|
**
|
|
|
|
|
** @see control::CommandDef usage example
|
2009-06-17 06:55:18 +02:00
|
|
|
** @see function-closure.hpp generic function application
|
2009-06-16 11:39:36 +02:00
|
|
|
** @see typelist.hpp
|
|
|
|
|
** @see tuple.hpp
|
|
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2011-12-03 02:56:50 +01:00
|
|
|
#ifndef LIB_META_FUNCTION_H
|
|
|
|
|
#define LIB_META_FUNCTION_H
|
2009-06-16 11:39:36 +02:00
|
|
|
|
|
|
|
|
#include "lib/meta/typelist.hpp"
|
|
|
|
|
|
2014-04-03 22:42:48 +02:00
|
|
|
#include <functional>
|
2009-06-16 11:39:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-12-03 02:56:50 +01:00
|
|
|
namespace lib {
|
|
|
|
|
namespace meta{
|
2009-06-16 11:39:36 +02:00
|
|
|
|
2014-04-03 22:42:48 +02:00
|
|
|
using std::function;
|
2009-06-17 06:55:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extract the type information contained in a
|
|
|
|
|
* function or functor type, so it can be manipulated
|
|
|
|
|
* by metaprogramming. Up to 9 function arguments are
|
|
|
|
|
* supported and can be extracted as a type sequence.
|
|
|
|
|
* The bare function signature serving as input can be
|
|
|
|
|
* obtained by capturing a function reference or pointer.
|
|
|
|
|
*/
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename SIG>
|
|
|
|
|
struct FunctionSignature;
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET>
|
|
|
|
|
struct FunctionSignature< function<RET(void)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<> Args;
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1> Args;
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2> Args;
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3> Args;
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3,A4)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3,A4> Args;
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3,A4,A5)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3,A4,A5> Args;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3,A4,A5,A6)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3,A4,A5,A6> Args;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3,A4,A5,A6,A7)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3,A4,A5,A6,A7> Args;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
, typename A8
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3,A4,A5,A6,A7,A8)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3,A4,A5,A6,A7,A8> Args;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
, typename A8
|
|
|
|
|
, typename A9
|
|
|
|
|
>
|
|
|
|
|
struct FunctionSignature< function<RET(A1,A2,A3,A4,A5,A6,A7,A8,A9)> >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<A1,A2,A3,A4,A5,A6,A7,A8,A9> Args;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-06-28 03:42:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper to dissect an arbitrary function signature,
|
|
|
|
|
* irrespective if the parameter is given as function reference,
|
|
|
|
|
* function pointer, member function pointer or functor object.
|
|
|
|
|
* The base case assumes a (language) function reference.
|
2016-03-25 19:58:09 +01:00
|
|
|
* @todo the base case should be a _generic functor_ where we
|
|
|
|
|
* pick up the signature through `decltype`, which also
|
|
|
|
|
* works with lambdas. See (\ref _ClosureType) //////////////////////////////////////TICKET #994
|
2012-06-28 03:42:48 +02:00
|
|
|
*/
|
Functor-Tools: reshape generic function signature trait to integrate Lambdas (#994)
As a first step towards a gradual rework of our function metaprogramming helpers,
this change prepends a generic case for all kinds of functors to our existing
solution, which up to now was entirely based on explicit specialisations.
C++11 supplied the new language construct 'decltype(EXPR)', which allows us
to capture any class with an function operator, which also includes the Lambdas.
The solution was proposed 2011 on StackOverflow
http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda/7943765#7943765
We used it already with success within our TreeMutator.
But obviously the goal should be to unite all the function trait / metaprogramming helpers,
which unfortunately is a more expensive undertaking, since it also involves
to get rid of the explicit specialisations and retrofit our Types<XXX...> helper
to rely on variadic templates rather than on loki-style typelists.
This first step here is rather conservative, since we'll still rely on our
explicit specialisations in most cases. Only the Lambdas will go through the
new, generic case, and from there invoke the specialisation for member functions.
The latter need to be rectified as well, which is subject of the next changeset...
2017-03-18 22:06:44 +01:00
|
|
|
template<typename FUN>
|
2012-06-28 03:42:48 +02:00
|
|
|
struct _Fun
|
Functor-Tools: reshape generic function signature trait to integrate Lambdas (#994)
As a first step towards a gradual rework of our function metaprogramming helpers,
this change prepends a generic case for all kinds of functors to our existing
solution, which up to now was entirely based on explicit specialisations.
C++11 supplied the new language construct 'decltype(EXPR)', which allows us
to capture any class with an function operator, which also includes the Lambdas.
The solution was proposed 2011 on StackOverflow
http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda/7943765#7943765
We used it already with success within our TreeMutator.
But obviously the goal should be to unite all the function trait / metaprogramming helpers,
which unfortunately is a more expensive undertaking, since it also involves
to get rid of the explicit specialisations and retrofit our Types<XXX...> helper
to rely on variadic templates rather than on loki-style typelists.
This first step here is rather conservative, since we'll still rely on our
explicit specialisations in most cases. Only the Lambdas will go through the
new, generic case, and from there invoke the specialisation for member functions.
The latter need to be rectified as well, which is subject of the next changeset...
2017-03-18 22:06:44 +01:00
|
|
|
: _Fun<decltype(&FUN::operator())>
|
|
|
|
|
{ };
|
|
|
|
|
|
|
|
|
|
/** Specialisation for a bare function signature */
|
|
|
|
|
template<typename RET, typename...ARGS>
|
|
|
|
|
struct _Fun<RET(ARGS...)>
|
2012-06-28 03:42:48 +02:00
|
|
|
{
|
Functor-Tools: reshape generic function signature trait to integrate Lambdas (#994)
As a first step towards a gradual rework of our function metaprogramming helpers,
this change prepends a generic case for all kinds of functors to our existing
solution, which up to now was entirely based on explicit specialisations.
C++11 supplied the new language construct 'decltype(EXPR)', which allows us
to capture any class with an function operator, which also includes the Lambdas.
The solution was proposed 2011 on StackOverflow
http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda/7943765#7943765
We used it already with success within our TreeMutator.
But obviously the goal should be to unite all the function trait / metaprogramming helpers,
which unfortunately is a more expensive undertaking, since it also involves
to get rid of the explicit specialisations and retrofit our Types<XXX...> helper
to rely on variadic templates rather than on loki-style typelists.
This first step here is rather conservative, since we'll still rely on our
explicit specialisations in most cases. Only the Lambdas will go through the
new, generic case, and from there invoke the specialisation for member functions.
The latter need to be rectified as well, which is subject of the next changeset...
2017-03-18 22:06:44 +01:00
|
|
|
using Ret = typename FunctionSignature<function<RET(ARGS...)>>::Ret ;
|
|
|
|
|
using Args = typename FunctionSignature<function<RET(ARGS...)>>::Args;
|
|
|
|
|
using Sig = RET(ARGS...);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
/** Specialisation for using a function pointer */
|
|
|
|
|
template<typename SIG>
|
|
|
|
|
struct _Fun<SIG*>
|
|
|
|
|
{
|
2016-12-23 04:23:03 +01:00
|
|
|
typedef typename FunctionSignature<function<SIG>>::Ret Ret;
|
|
|
|
|
typedef typename FunctionSignature<function<SIG>>::Args Args;
|
|
|
|
|
typedef SIG Sig;
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
2012-09-01 17:33:42 +02:00
|
|
|
/** Specialisation when using a function reference */
|
|
|
|
|
template<typename SIG>
|
|
|
|
|
struct _Fun<SIG&>
|
|
|
|
|
{
|
2016-12-23 04:23:03 +01:00
|
|
|
typedef typename FunctionSignature<function<SIG>>::Ret Ret;
|
|
|
|
|
typedef typename FunctionSignature<function<SIG>>::Args Args;
|
|
|
|
|
typedef SIG Sig;
|
2012-09-01 17:33:42 +02:00
|
|
|
};
|
2012-06-28 03:42:48 +02:00
|
|
|
/** Specialisation for passing a functor */
|
|
|
|
|
template<typename SIG>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct _Fun<function<SIG>>
|
2012-06-28 03:42:48 +02:00
|
|
|
{
|
2016-12-23 04:23:03 +01:00
|
|
|
typedef typename FunctionSignature<function<SIG>>::Ret Ret;
|
|
|
|
|
typedef typename FunctionSignature<function<SIG>>::Args Args;
|
|
|
|
|
typedef SIG Sig;
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Specialisations for member function pointers */
|
2017-03-19 00:19:07 +01:00
|
|
|
/* template<typename RET, class CLASS>
|
2012-06-28 03:42:48 +02:00
|
|
|
struct _Fun<RET (CLASS::*) (void) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1> Args;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2,A3) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2,A3> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2,A3);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2,A3,A4) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2,A3,A4> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2,A3,A4);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2,A3,A4,A5) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2,A3,A4,A5> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2,A3,A4,A5);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2,A3,A4,A5,A6) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2,A3,A4,A5,A6> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2,A3,A4,A5,A6);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2,A3,A4,A5,A6,A7) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2,A3,A4,A5,A6,A7> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2,A3,A4,A5,A6,A7);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template< typename RET, class CLASS
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
, typename A8
|
|
|
|
|
>
|
|
|
|
|
struct _Fun<RET (CLASS::*) (A1,A2,A3,A4,A5,A6,A7,A8) >
|
|
|
|
|
{
|
|
|
|
|
typedef RET Ret;
|
|
|
|
|
typedef Types<CLASS* const, A1,A2,A3,A4,A5,A6,A7,A8> Args;
|
2015-09-04 17:14:11 +02:00
|
|
|
typedef RET Sig(CLASS* const, A1,A2,A3,A4,A5,A6,A7,A8);
|
2012-06-28 03:42:48 +02:00
|
|
|
};
|
2017-03-19 00:19:07 +01:00
|
|
|
*/
|
2012-06-28 03:42:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename FUN>
|
|
|
|
|
struct is_Functor { static const bool value = false; };
|
|
|
|
|
template<typename SIG>
|
|
|
|
|
struct is_Functor<function<SIG> > { static const bool value = true; };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
/**
|
|
|
|
|
* Build function types from given Argument types.
|
|
|
|
|
* As embedded typedefs, you'll find a tr1 functor #Func
|
|
|
|
|
* and the bare function signature #Sig
|
|
|
|
|
* @param RET the function return type
|
|
|
|
|
* @param ARGS a type sequence describing the arguments
|
|
|
|
|
*/
|
|
|
|
|
template<typename RET, typename ARGS>
|
2009-06-16 11:39:36 +02:00
|
|
|
struct FunctionTypedef;
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET>
|
|
|
|
|
struct FunctionTypedef<RET, Types<> >
|
|
|
|
|
{
|
|
|
|
|
typedef function<RET(void)> Func;
|
|
|
|
|
typedef RET Sig();
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1>>
|
2009-06-16 11:39:36 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1)> Func;
|
|
|
|
|
typedef RET Sig(A1);
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2>>
|
2009-06-16 11:39:36 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2);
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3>>
|
2009-06-16 11:39:36 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2,A3)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3);
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3,A4>>
|
2009-06-16 11:39:36 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2,A3,A4)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3,A4);
|
|
|
|
|
};
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
|
2009-06-16 11:39:36 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5>>
|
2009-06-16 11:39:36 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2,A3,A4,A5)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3,A4,A5);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6>>
|
2009-06-17 06:55:18 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2,A3,A4,A5,A6)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3,A4,A5,A6);
|
|
|
|
|
};
|
2009-06-16 11:39:36 +02:00
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
2009-06-16 11:39:36 +02:00
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
2009-06-17 06:55:18 +02:00
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
2009-06-16 11:39:36 +02:00
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6,A7>>
|
2009-06-16 11:39:36 +02:00
|
|
|
{
|
2009-06-17 06:55:18 +02:00
|
|
|
typedef function<RET(A1,A2,A3,A4,A5,A6,A7)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3,A4,A5,A6,A7);
|
2009-06-16 11:39:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
, typename A8
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6,A7,A8>>
|
2009-06-17 06:55:18 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2,A3,A4,A5,A6,A7,A8)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3,A4,A5,A6,A7,A8);
|
|
|
|
|
};
|
2009-06-16 11:39:36 +02:00
|
|
|
|
|
|
|
|
|
2009-06-17 06:55:18 +02:00
|
|
|
template< typename RET
|
|
|
|
|
, typename A1
|
|
|
|
|
, typename A2
|
|
|
|
|
, typename A3
|
|
|
|
|
, typename A4
|
|
|
|
|
, typename A5
|
|
|
|
|
, typename A6
|
|
|
|
|
, typename A7
|
|
|
|
|
, typename A8
|
|
|
|
|
, typename A9
|
|
|
|
|
>
|
2016-12-23 04:23:03 +01:00
|
|
|
struct FunctionTypedef<RET, Types<A1,A2,A3,A4,A5,A6,A7,A8,A9>>
|
2009-06-17 06:55:18 +02:00
|
|
|
{
|
|
|
|
|
typedef function<RET(A1,A2,A3,A4,A5,A6,A7,A8,A9)> Func;
|
|
|
|
|
typedef RET Sig(A1,A2,A3,A4,A5,A6,A7,A8,A9);
|
|
|
|
|
};
|
2009-06-16 11:39:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-12-03 02:56:50 +01:00
|
|
|
}} // namespace lib::meta
|
2009-06-16 11:39:36 +02:00
|
|
|
#endif
|