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)
|
---|