[857] | 1 | ///////////////////////////////////////////////////////////////////////////////
|
---|
| 2 | //
|
---|
| 3 | // Copyright David Abrahams 2002, Joel de Guzman, 2002.
|
---|
| 4 | // Distributed under the Boost Software License, Version 1.0. (See
|
---|
| 5 | // accompanying file LICENSE_1_0.txt or copy at
|
---|
| 6 | // http://www.boost.org/LICENSE_1_0.txt)
|
---|
| 7 | //
|
---|
| 8 | ///////////////////////////////////////////////////////////////////////////////
|
---|
| 9 | #if !defined(BOOST_PP_IS_ITERATING)
|
---|
| 10 |
|
---|
| 11 | # ifndef SIGNATURE_JDG20020813_HPP
|
---|
| 12 | # define SIGNATURE_JDG20020813_HPP
|
---|
| 13 |
|
---|
| 14 | # include <boost/python/detail/prefix.hpp>
|
---|
| 15 |
|
---|
| 16 | # include <boost/mpl/if.hpp>
|
---|
| 17 | # include <boost/type_traits/is_convertible.hpp>
|
---|
| 18 |
|
---|
| 19 | # include <boost/python/detail/preprocessor.hpp>
|
---|
| 20 | # include <boost/preprocessor/repeat.hpp>
|
---|
| 21 | # include <boost/preprocessor/enum.hpp>
|
---|
| 22 | # include <boost/preprocessor/enum_params.hpp>
|
---|
| 23 | # include <boost/preprocessor/empty.hpp>
|
---|
| 24 | # include <boost/preprocessor/arithmetic/sub.hpp>
|
---|
| 25 | # include <boost/preprocessor/iterate.hpp>
|
---|
| 26 | # include <boost/python/detail/type_list.hpp>
|
---|
| 27 |
|
---|
| 28 | # include <boost/preprocessor/debug/line.hpp>
|
---|
| 29 | # include <boost/preprocessor/arithmetic/sub.hpp>
|
---|
| 30 | # include <boost/preprocessor/arithmetic/inc.hpp>
|
---|
| 31 | # include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
---|
| 32 |
|
---|
| 33 | # define BOOST_PYTHON_LIST_INC(n) \
|
---|
| 34 | BOOST_PP_CAT(mpl::vector, BOOST_PP_INC(n))
|
---|
| 35 |
|
---|
| 36 | ///////////////////////////////////////////////////////////////////////////////
|
---|
| 37 | namespace boost { namespace python { namespace detail {
|
---|
| 38 |
|
---|
| 39 | // A metafunction returning C1 if C1 is derived from C2, and C2
|
---|
| 40 | // otherwise
|
---|
| 41 | template <class C1, class C2>
|
---|
| 42 | struct most_derived
|
---|
| 43 | {
|
---|
| 44 | typedef typename mpl::if_<
|
---|
| 45 | is_convertible<C1*,C2*>
|
---|
| 46 | , C1
|
---|
| 47 | , C2
|
---|
| 48 | >::type type;
|
---|
| 49 | };
|
---|
| 50 |
|
---|
| 51 | // The following macros generate expansions for::
|
---|
| 52 | //
|
---|
| 53 | // template <class RT, class T0... class TN>
|
---|
| 54 | // inline mpl::vector<RT, T0...TN>
|
---|
| 55 | // get_signature(RT(*)(T0...TN), void* = 0)
|
---|
| 56 | // {
|
---|
| 57 | // return mpl::list<RT, T0...TN>();
|
---|
| 58 | // }
|
---|
| 59 | //
|
---|
| 60 | // And, for an appropriate assortment of cv-qualifications::
|
---|
| 61 | //
|
---|
| 62 | // template <class RT, class ClassT, class T0... class TN>
|
---|
| 63 | // inline mpl::vector<RT, ClassT&, T0...TN>
|
---|
| 64 | // get_signature(RT(ClassT::*)(T0...TN) cv))
|
---|
| 65 | // {
|
---|
| 66 | // return mpl::list<RT, ClassT&, T0...TN>();
|
---|
| 67 | // }
|
---|
| 68 | //
|
---|
| 69 | // template <class Target, class RT, class ClassT, class T0... class TN>
|
---|
| 70 | // inline mpl::vector<
|
---|
| 71 | // RT
|
---|
| 72 | // , typename most_derived<Target, ClassT>::type&
|
---|
| 73 | // , T0...TN
|
---|
| 74 | // >
|
---|
| 75 | // get_signature(RT(ClassT::*)(T0...TN) cv), Target*)
|
---|
| 76 | // {
|
---|
| 77 | // return mpl::list<RT, ClassT&, T0...TN>();
|
---|
| 78 | // }
|
---|
| 79 | //
|
---|
| 80 | // There are two forms for invoking get_signature::
|
---|
| 81 | //
|
---|
| 82 | // get_signature(f)
|
---|
| 83 | //
|
---|
| 84 | // and ::
|
---|
| 85 | //
|
---|
| 86 | // get_signature(f,(Target*)0)
|
---|
| 87 | //
|
---|
| 88 | // These functions extract the return type, class (for member
|
---|
| 89 | // functions) and arguments of the input signature and stuff them in
|
---|
| 90 | // an mpl type sequence. Note that cv-qualification is dropped from
|
---|
| 91 | // the "hidden this" argument of member functions; that is a
|
---|
| 92 | // necessary sacrifice to ensure that an lvalue from_python converter
|
---|
| 93 | // is used. A pointer is not used so that None will be rejected for
|
---|
| 94 | // overload resolution.
|
---|
| 95 | //
|
---|
| 96 | // The second form of get_signature essentially downcasts the "hidden
|
---|
| 97 | // this" argument of member functions to Target, because the function
|
---|
| 98 | // may actually be a member of a base class which is not wrapped, and
|
---|
| 99 | // in that case conversion from python would fail.
|
---|
| 100 | //
|
---|
| 101 | // @group {
|
---|
| 102 |
|
---|
| 103 | # define BOOST_PP_ITERATION_PARAMS_1 \
|
---|
| 104 | (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>))
|
---|
| 105 |
|
---|
| 106 | # include BOOST_PP_ITERATE()
|
---|
| 107 | # undef BOOST_PYTHON_LIST_INC
|
---|
| 108 |
|
---|
| 109 | // }
|
---|
| 110 |
|
---|
| 111 | }}} // namespace boost::python::detail
|
---|
| 112 |
|
---|
| 113 |
|
---|
| 114 | # endif // SIGNATURE_JDG20020813_HPP
|
---|
| 115 |
|
---|
| 116 | #elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING)
|
---|
| 117 |
|
---|
| 118 | # define N BOOST_PP_ITERATION()
|
---|
| 119 |
|
---|
| 120 | template <
|
---|
| 121 | class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
|
---|
| 122 | inline BOOST_PYTHON_LIST_INC(N)<
|
---|
| 123 | RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
|
---|
| 124 | get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0)
|
---|
| 125 | {
|
---|
| 126 | return BOOST_PYTHON_LIST_INC(N)<
|
---|
| 127 | RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
|
---|
| 128 | >();
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | # undef N
|
---|
| 132 |
|
---|
| 133 | # define BOOST_PP_ITERATION_PARAMS_2 \
|
---|
| 134 | (3, (0, 3, <boost/python/signature.hpp>))
|
---|
| 135 | # include BOOST_PP_ITERATE()
|
---|
| 136 |
|
---|
| 137 | #else
|
---|
| 138 |
|
---|
| 139 | # define N BOOST_PP_RELATIVE_ITERATION(1)
|
---|
| 140 | # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION())
|
---|
| 141 |
|
---|
| 142 | template <
|
---|
| 143 | class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)>
|
---|
| 144 | inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
|
---|
| 145 | RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)>
|
---|
| 146 | get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q)
|
---|
| 147 | {
|
---|
| 148 | return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
|
---|
| 149 | RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
|
---|
| 150 | >();
|
---|
| 151 | }
|
---|
| 152 |
|
---|
| 153 | template <
|
---|
| 154 | class Target
|
---|
| 155 | , class RT
|
---|
| 156 | , class ClassT
|
---|
| 157 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)
|
---|
| 158 | >
|
---|
| 159 | inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
|
---|
| 160 | RT
|
---|
| 161 | , typename most_derived<Target, ClassT>::type&
|
---|
| 162 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
|
---|
| 163 | >
|
---|
| 164 | get_signature(
|
---|
| 165 | RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q
|
---|
| 166 | , Target*
|
---|
| 167 | )
|
---|
| 168 | {
|
---|
| 169 | return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))<
|
---|
| 170 | RT
|
---|
| 171 | , BOOST_DEDUCED_TYPENAME most_derived<Target, ClassT>::type&
|
---|
| 172 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)
|
---|
| 173 | >();
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | # undef Q
|
---|
| 177 | # undef N
|
---|
| 178 |
|
---|
| 179 | #endif // !defined(BOOST_PP_IS_ITERATING)
|
---|