1 // Copyright Daniel Wallin 2008. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #if !BOOST_PP_IS_ITERATING
7 # ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
8 # define LUABIND_DEDUCE_SIGNATURE_080911_HPP
10 # include <luabind/detail/most_derived.hpp>
11 # include <luabind/vector.hpp>
13 # ifndef LUABIND_CPP0x
14 # if LUABIND_MAX_ARITY <= 8
15 # include <boost/mpl/vector/vector10.hpp>
17 # include <boost/mpl/vector/vector50.hpp>
19 # include <boost/preprocessor/cat.hpp>
20 # include <boost/preprocessor/iteration/iterate.hpp>
21 # include <boost/preprocessor/repetition/enum_params.hpp>
24 namespace luabind
{ namespace detail
{
28 template <class R
, class... Args
>
29 vector
<R
, Args
...> deduce_signature(R(*)(Args
...), ...)
31 return vector
<R
, Args
...>();
34 template <class R
, class T
, class... Args
>
35 vector
<R
, T
&, Args
...> deduce_signature(R(T::*)(Args
...))
37 return vector
<R
, T
&, Args
...>();
40 template <class R
, class T
, class Wrapped
, class... Args
>
41 vector
<R
, typename most_derived
<T
,Wrapped
>::type
&, Args
...>
42 deduce_signature(R(T::*)(Args
...), Wrapped
*)
44 return vector
<R
, typename most_derived
<T
,Wrapped
>::type
&, Args
...>();
47 template <class R
, class T
, class... Args
>
48 vector
<R
, T
const&, Args
...> deduce_signature(R(T::*)(Args
...) const)
50 return vector
<R
, T
const&, Args
...>();
53 template <class R
, class T
, class Wrapped
, class... Args
>
54 vector
<R
, typename most_derived
<T
,Wrapped
>::type
const&, Args
...>
55 deduce_signature(R(T::*)(Args
...) const, Wrapped
*)
57 return vector
<R
, typename most_derived
<T
,Wrapped
>::type
const&, Args
...>();
60 // This is primarily intended to catch C++0x lambda closures. It figures out
61 // the signature of a function object, and strips the object type from the
62 // resulting signature:
64 // vector<void, unspecified const&, ...>
70 // This overload is all luabind needs to correctly handle monomorphic function
71 // objects with a fixed signature such as C++0x lambdas. The standard doesn't
72 // explicitly say that an implementation isn't allowed to add additional
73 // overloads of operator() to the closure type, in practice however, noone
76 template <class Signature
>
77 struct strip_this_argument
;
79 template <class R
, class T
, class... Args
>
80 struct strip_this_argument
<vector
<R
, T
, Args
...> >
82 typedef vector
<R
, Args
...> type
;
86 typename strip_this_argument
<
87 decltype(deduce_signature(&F::operator()))
88 >::type
deduce_signature(F
const&)
90 return typename strip_this_argument
<
91 decltype(deduce_signature(&F::operator()))>::type();
94 # else // LUABIND_CPP0x
96 namespace mpl
= boost::mpl
;
99 mpl::vector1
<R
> deduce_signature(R(*)(), ...)
101 return mpl::vector1
<R
>();
104 template <class R
, class T
>
105 mpl::vector2
<R
,T
&> deduce_signature(R(T::*)())
107 return mpl::vector2
<R
,T
&>();
110 template <class R
, class T
, class Wrapped
>
111 mpl::vector2
<R
,typename most_derived
<T
,Wrapped
>::type
&>
112 deduce_signature(R(T::*)(), Wrapped
*)
114 return mpl::vector2
<R
,typename most_derived
<T
,Wrapped
>::type
&>();
117 template <class R
, class T
>
118 mpl::vector2
<R
,T
const&> deduce_signature(R(T::*)() const)
120 return mpl::vector2
<R
,T
const&>();
123 template <class R
, class T
, class Wrapped
>
124 mpl::vector2
<R
,typename most_derived
<T
,Wrapped
>::type
const&>
125 deduce_signature(R(T::*)() const, Wrapped
*)
127 return mpl::vector2
<R
,typename most_derived
<T
,Wrapped
>::type
const&>();
130 # define BOOST_PP_ITERATION_PARAMS_1 \
131 (3, (1, LUABIND_MAX_ARITY, <luabind/detail/deduce_signature.hpp>))
132 # include BOOST_PP_ITERATE()
134 # endif // LUABIND_CPP0x
136 }} // namespace luabind::detail
138 # endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP
140 #else // BOOST_PP_IS_ITERATING
142 # define N BOOST_PP_ITERATION()
143 # define NPLUS1 BOOST_PP_INC(N)
145 template <class R
, BOOST_PP_ENUM_PARAMS(N
,class A
)>
146 BOOST_PP_CAT(mpl::vector
,NPLUS1
)<R
, BOOST_PP_ENUM_PARAMS(N
,A
)>
147 deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N
,A
)), ...)
149 return BOOST_PP_CAT(mpl::vector
,NPLUS1
)<R
,BOOST_PP_ENUM_PARAMS(N
,A
)>();
152 # define NPLUS2 BOOST_PP_INC(NPLUS1)
154 template <class R
, class T
, BOOST_PP_ENUM_PARAMS(N
,class A
)>
155 BOOST_PP_CAT(mpl::vector
,NPLUS2
)<R
, T
&, BOOST_PP_ENUM_PARAMS(N
,A
)>
156 deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N
,A
)))
158 return BOOST_PP_CAT(mpl::vector
,NPLUS2
)<R
,T
&,BOOST_PP_ENUM_PARAMS(N
,A
)>();
161 template <class R
, class T
, BOOST_PP_ENUM_PARAMS(N
,class A
), class Wrapped
>
162 BOOST_PP_CAT(mpl::vector
,NPLUS2
)<
163 R
, typename most_derived
<T
,Wrapped
>::type
&, BOOST_PP_ENUM_PARAMS(N
,A
)
165 deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N
,A
)), Wrapped
*)
167 return BOOST_PP_CAT(mpl::vector
,NPLUS2
)<
168 R
,typename most_derived
<T
,Wrapped
>::type
&,BOOST_PP_ENUM_PARAMS(N
,A
)>();
171 template <class R
, class T
, BOOST_PP_ENUM_PARAMS(N
,class A
)>
172 BOOST_PP_CAT(mpl::vector
,NPLUS2
)<R
, T
const&, BOOST_PP_ENUM_PARAMS(N
,A
)>
173 deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N
,A
)) const)
175 return BOOST_PP_CAT(mpl::vector
,NPLUS2
)<R
,T
const&,BOOST_PP_ENUM_PARAMS(N
,A
)>();
178 template <class R
, class T
, BOOST_PP_ENUM_PARAMS(N
,class A
), class Wrapped
>
179 BOOST_PP_CAT(mpl::vector
,NPLUS2
)<
180 R
, typename most_derived
<T
,Wrapped
>::type
const&, BOOST_PP_ENUM_PARAMS(N
,A
)
182 deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N
,A
)) const, Wrapped
*)
184 return BOOST_PP_CAT(mpl::vector
,NPLUS2
)<
185 R
,typename most_derived
<T
,Wrapped
>::type
const&,BOOST_PP_ENUM_PARAMS(N
,A
)>();
192 #endif // BOOST_PP_IS_ITERATING