]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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(BOOST_PYTHON_FN_CC *)(T0...TN), void* = 0) | |
56 | // { | |
57 | // return mpl::list<RT, T0...TN>(); | |
58 | // } | |
59 | // | |
60 | // where BOOST_PYTHON_FN_CC is a calling convention keyword, can be | |
61 | // | |
62 | // empty, for default calling convention | |
63 | // __cdecl (if BOOST_PYTHON_ENABLE_CDECL is defined) | |
64 | // __stdcall (if BOOST_PYTHON_ENABLE_STDCALL is defined) | |
65 | // __fastcall (if BOOST_PYTHON_ENABLE_FASTCALL is defined) | |
66 | // | |
67 | // And, for an appropriate assortment of cv-qualifications:: | |
68 | // | |
69 | // template <class RT, class ClassT, class T0... class TN> | |
70 | // inline mpl::vector<RT, ClassT&, T0...TN> | |
71 | // get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv)) | |
72 | // { | |
73 | // return mpl::list<RT, ClassT&, T0...TN>(); | |
74 | // } | |
75 | // | |
76 | // template <class Target, class RT, class ClassT, class T0... class TN> | |
77 | // inline mpl::vector< | |
78 | // RT | |
79 | // , typename most_derived<Target, ClassT>::type& | |
80 | // , T0...TN | |
81 | // > | |
82 | // get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(T0...TN) cv), Target*) | |
83 | // { | |
84 | // return mpl::list<RT, ClassT&, T0...TN>(); | |
85 | // } | |
86 | // | |
87 | // There are two forms for invoking get_signature:: | |
88 | // | |
89 | // get_signature(f) | |
90 | // | |
91 | // and :: | |
92 | // | |
93 | // get_signature(f,(Target*)0) | |
94 | // | |
95 | // These functions extract the return type, class (for member | |
96 | // functions) and arguments of the input signature and stuff them in | |
97 | // an mpl type sequence (the calling convention is dropped). | |
98 | // Note that cv-qualification is dropped from | |
99 | // the "hidden this" argument of member functions; that is a | |
100 | // necessary sacrifice to ensure that an lvalue from_python converter | |
101 | // is used. A pointer is not used so that None will be rejected for | |
102 | // overload resolution. | |
103 | // | |
104 | // The second form of get_signature essentially downcasts the "hidden | |
105 | // this" argument of member functions to Target, because the function | |
106 | // may actually be a member of a base class which is not wrapped, and | |
107 | // in that case conversion from python would fail. | |
108 | // | |
109 | // @group { | |
110 | ||
111 | // 'default' calling convention | |
112 | ||
113 | # define BOOST_PYTHON_FN_CC | |
114 | # define BOOST_PYTHON_FN_CC_IS_DEFAULT | |
115 | ||
116 | # define BOOST_PP_ITERATION_PARAMS_1 \ | |
117 | (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>)) | |
118 | ||
119 | # include BOOST_PP_ITERATE() | |
120 | ||
121 | # undef BOOST_PYTHON_FN_CC | |
122 | # undef BOOST_PYTHON_FN_CC_IS_DEFAULT | |
123 | ||
124 | // __cdecl calling convention | |
125 | ||
126 | # if defined(BOOST_PYTHON_ENABLE_CDECL) | |
127 | ||
128 | # define BOOST_PYTHON_FN_CC __cdecl | |
129 | # define BOOST_PYTHON_FN_CC_IS_CDECL | |
130 | ||
131 | # define BOOST_PP_ITERATION_PARAMS_1 \ | |
132 | (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>)) | |
133 | ||
134 | # include BOOST_PP_ITERATE() | |
135 | ||
136 | # undef BOOST_PYTHON_FN_CC | |
137 | # undef BOOST_PYTHON_FN_CC_IS_CDECL | |
138 | ||
139 | # endif // defined(BOOST_PYTHON_ENABLE_CDECL) | |
140 | ||
141 | // __stdcall calling convention | |
142 | ||
143 | # if defined(BOOST_PYTHON_ENABLE_STDCALL) | |
144 | ||
145 | # define BOOST_PYTHON_FN_CC __stdcall | |
146 | # define BOOST_PYTHON_FN_CC_IS_STDCALL | |
147 | ||
148 | # define BOOST_PP_ITERATION_PARAMS_1 \ | |
149 | (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>)) | |
150 | ||
151 | # include BOOST_PP_ITERATE() | |
152 | ||
153 | # undef BOOST_PYTHON_FN_CC | |
154 | # undef BOOST_PYTHON_FN_CC_IS_STDCALL | |
155 | ||
156 | # endif // defined(BOOST_PYTHON_ENABLE_STDCALL) | |
157 | ||
158 | // __fastcall calling convention | |
159 | ||
160 | # if defined(BOOST_PYTHON_ENABLE_FASTCALL) | |
161 | ||
162 | # define BOOST_PYTHON_FN_CC __fastcall | |
163 | # define BOOST_PYTHON_FN_CC_IS_FASTCALL | |
164 | ||
165 | # define BOOST_PP_ITERATION_PARAMS_1 \ | |
166 | (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/signature.hpp>)) | |
167 | ||
168 | # include BOOST_PP_ITERATE() | |
169 | ||
170 | # undef BOOST_PYTHON_FN_CC_IS_FASTCALL | |
171 | # undef BOOST_PYTHON_FN_CC | |
172 | ||
173 | # endif // defined(BOOST_PYTHON_ENABLE_FASTCALL) | |
174 | ||
175 | # undef BOOST_PYTHON_LIST_INC | |
176 | ||
177 | // } | |
178 | ||
179 | }}} // namespace boost::python::detail | |
180 | ||
181 | ||
182 | # endif // SIGNATURE_JDG20020813_HPP | |
183 | ||
184 | // For gcc 4.4 compatability, we must include the | |
185 | // BOOST_PP_ITERATION_DEPTH test inside an #else clause. | |
186 | #else // BOOST_PP_IS_ITERATING | |
187 | #if BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING) | |
188 | ||
189 | # define N BOOST_PP_ITERATION() | |
190 | ||
191 | // as 'get_signature(RT(*)(T0...TN), void* = 0)' is the same | |
192 | // function as 'get_signature(RT(__cdecl *)(T0...TN), void* = 0)', | |
193 | // we don't define it multiple times (i.e. for __cdecl, __stdcall ...) | |
194 | # if defined(BOOST_PYTHON_FN_CC_IS_DEFAULT) | |
195 | ||
196 | template < | |
197 | class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> | |
198 | inline BOOST_PYTHON_LIST_INC(N)< | |
199 | RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> | |
200 | get_signature(RT(BOOST_PYTHON_FN_CC *)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)), void* = 0) | |
201 | { | |
202 | return BOOST_PYTHON_LIST_INC(N)< | |
203 | RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) | |
204 | >(); | |
205 | } | |
206 | ||
207 | # endif // BOOST_PYTHON_FN_CC_IS_DEFAULT | |
208 | ||
209 | # undef N | |
210 | ||
211 | # define BOOST_PP_ITERATION_PARAMS_2 \ | |
212 | (3, (0, 3, <boost/python/signature.hpp>)) | |
213 | # include BOOST_PP_ITERATE() | |
214 | ||
215 | #else // BOOST_PP_ITERATION_DEPTH() != 1 | |
216 | ||
217 | # define N BOOST_PP_RELATIVE_ITERATION(1) | |
218 | # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION()) | |
219 | ||
220 | # if defined(BOOST_PYTHON_FN_CC_IS_DEFAULT) | |
221 | ||
222 | template < | |
223 | class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> | |
224 | inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< | |
225 | RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> | |
226 | get_signature(RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) | |
227 | { | |
228 | return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< | |
229 | RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) | |
230 | >(); | |
231 | } | |
232 | ||
233 | template < | |
234 | class Target | |
235 | , class RT | |
236 | , class ClassT | |
237 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T) | |
238 | > | |
239 | inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< | |
240 | RT | |
241 | , typename most_derived<Target, ClassT>::type& | |
242 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) | |
243 | > | |
244 | get_signature( | |
245 | RT(BOOST_PYTHON_FN_CC ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q | |
246 | , Target* | |
247 | ) | |
248 | { | |
249 | return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< | |
250 | RT | |
251 | , BOOST_DEDUCED_TYPENAME most_derived<Target, ClassT>::type& | |
252 | BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) | |
253 | >(); | |
254 | } | |
255 | ||
256 | # endif // BOOST_PYTHON_FN_CC_IS_DEFAULT | |
257 | ||
258 | # undef Q | |
259 | # undef N | |
260 | ||
261 | #endif // BOOST_PP_ITERATION_DEPTH() | |
262 | #endif // !defined(BOOST_PP_IS_ITERATING) |