Initial C++0x support.
[luabind.git] / luabind / detail / deduce_signature.hpp
bloba2160ea68ec3137cf12ae7ce3c046d1b5e81a08a
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>
16 # else
17 # include <boost/mpl/vector/vector50.hpp>
18 # endif
19 # include <boost/preprocessor/cat.hpp>
20 # include <boost/preprocessor/iteration/iterate.hpp>
21 # include <boost/preprocessor/repetition/enum_params.hpp>
22 # endif
24 namespace luabind { namespace detail {
26 # ifdef LUABIND_CPP0x
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&, ...>
66 // into
68 // vector<void, ...>
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
74 // seems to.
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;
85 template <class F>
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;
98 template <class R>
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)>();
188 # undef NPLUS2
189 # undef NPLUS1
190 # undef N
192 #endif // BOOST_PP_IS_ITERATING