sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // Copyright David Abrahams 2002, Joel de Guzman, 2002. sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: #if !defined(BOOST_PP_IS_ITERATING) sl@0: sl@0: # ifndef SIGNATURE_JDG20020813_HPP sl@0: # define SIGNATURE_JDG20020813_HPP sl@0: sl@0: # include sl@0: sl@0: # include sl@0: # include sl@0: sl@0: # include sl@0: # include sl@0: # include sl@0: # include sl@0: # include sl@0: # include sl@0: # include sl@0: # include sl@0: sl@0: # include sl@0: # include sl@0: # include sl@0: # include sl@0: sl@0: # define BOOST_PYTHON_LIST_INC(n) \ sl@0: BOOST_PP_CAT(mpl::vector, BOOST_PP_INC(n)) sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: namespace boost { namespace python { namespace detail { sl@0: sl@0: // A metafunction returning C1 if C1 is derived from C2, and C2 sl@0: // otherwise sl@0: template sl@0: struct most_derived sl@0: { sl@0: typedef typename mpl::if_< sl@0: is_convertible sl@0: , C1 sl@0: , C2 sl@0: >::type type; sl@0: }; sl@0: sl@0: // The following macros generate expansions for:: sl@0: // sl@0: // template sl@0: // inline mpl::vector sl@0: // get_signature(RT(*)(T0...TN), void* = 0) sl@0: // { sl@0: // return mpl::list(); sl@0: // } sl@0: // sl@0: // And, for an appropriate assortment of cv-qualifications:: sl@0: // sl@0: // template sl@0: // inline mpl::vector sl@0: // get_signature(RT(ClassT::*)(T0...TN) cv)) sl@0: // { sl@0: // return mpl::list(); sl@0: // } sl@0: // sl@0: // template sl@0: // inline mpl::vector< sl@0: // RT sl@0: // , typename most_derived::type& sl@0: // , T0...TN sl@0: // > sl@0: // get_signature(RT(ClassT::*)(T0...TN) cv), Target*) sl@0: // { sl@0: // return mpl::list(); sl@0: // } sl@0: // sl@0: // There are two forms for invoking get_signature:: sl@0: // sl@0: // get_signature(f) sl@0: // sl@0: // and :: sl@0: // sl@0: // get_signature(f,(Target*)0) sl@0: // sl@0: // These functions extract the return type, class (for member sl@0: // functions) and arguments of the input signature and stuff them in sl@0: // an mpl type sequence. Note that cv-qualification is dropped from sl@0: // the "hidden this" argument of member functions; that is a sl@0: // necessary sacrifice to ensure that an lvalue from_python converter sl@0: // is used. A pointer is not used so that None will be rejected for sl@0: // overload resolution. sl@0: // sl@0: // The second form of get_signature essentially downcasts the "hidden sl@0: // this" argument of member functions to Target, because the function sl@0: // may actually be a member of a base class which is not wrapped, and sl@0: // in that case conversion from python would fail. sl@0: // sl@0: // @group { sl@0: sl@0: # define BOOST_PP_ITERATION_PARAMS_1 \ sl@0: (3, (0, BOOST_PYTHON_MAX_ARITY, )) sl@0: sl@0: # include BOOST_PP_ITERATE() sl@0: # undef BOOST_PYTHON_LIST_INC sl@0: sl@0: // } sl@0: sl@0: }}} // namespace boost::python::detail sl@0: sl@0: sl@0: # endif // SIGNATURE_JDG20020813_HPP sl@0: sl@0: #elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING) sl@0: sl@0: # define N BOOST_PP_ITERATION() sl@0: sl@0: template < sl@0: class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> sl@0: inline BOOST_PYTHON_LIST_INC(N)< sl@0: RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> sl@0: get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0) sl@0: { sl@0: return BOOST_PYTHON_LIST_INC(N)< sl@0: RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) sl@0: >(); sl@0: } sl@0: sl@0: # undef N sl@0: sl@0: # define BOOST_PP_ITERATION_PARAMS_2 \ sl@0: (3, (0, 3, )) sl@0: # include BOOST_PP_ITERATE() sl@0: sl@0: #else sl@0: sl@0: # define N BOOST_PP_RELATIVE_ITERATION(1) sl@0: # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION()) sl@0: sl@0: template < sl@0: class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> sl@0: inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< sl@0: RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> sl@0: get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) sl@0: { sl@0: return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< sl@0: RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) sl@0: >(); sl@0: } sl@0: sl@0: template < sl@0: class Target sl@0: , class RT sl@0: , class ClassT sl@0: BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T) sl@0: > sl@0: inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< sl@0: RT sl@0: , typename most_derived::type& sl@0: BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) sl@0: > sl@0: get_signature( sl@0: RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q sl@0: , Target* sl@0: ) sl@0: { sl@0: return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< sl@0: RT sl@0: , BOOST_DEDUCED_TYPENAME most_derived::type& sl@0: BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) sl@0: >(); sl@0: } sl@0: sl@0: # undef Q sl@0: # undef N sl@0: sl@0: #endif // !defined(BOOST_PP_IS_ITERATING)