Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/python/detail/caller.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 #if !defined(BOOST_PP_IS_ITERATING) | |
2 | |
3 // Copyright David Abrahams 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 # ifndef CALLER_DWA20021121_HPP | |
9 # define CALLER_DWA20021121_HPP | |
10 | |
11 # include <boost/python/type_id.hpp> | |
12 # include <boost/python/handle.hpp> | |
13 | |
14 # include <boost/detail/indirect_traits.hpp> | |
15 | |
16 # include <boost/python/detail/invoke.hpp> | |
17 # include <boost/python/detail/signature.hpp> | |
18 # include <boost/python/detail/preprocessor.hpp> | |
19 | |
20 # include <boost/python/arg_from_python.hpp> | |
21 # include <boost/python/converter/context_result_converter.hpp> | |
22 # include <boost/python/converter/builtin_converters.hpp> | |
23 | |
24 # include <boost/preprocessor/iterate.hpp> | |
25 # include <boost/preprocessor/cat.hpp> | |
26 # include <boost/preprocessor/dec.hpp> | |
27 # include <boost/preprocessor/if.hpp> | |
28 # include <boost/preprocessor/iteration/local.hpp> | |
29 # include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
30 # include <boost/preprocessor/repetition/repeat.hpp> | |
31 | |
32 # include <boost/compressed_pair.hpp> | |
33 | |
34 # include <boost/type_traits/is_same.hpp> | |
35 # include <boost/type_traits/is_convertible.hpp> | |
36 | |
37 # include <boost/mpl/apply.hpp> | |
38 # include <boost/mpl/eval_if.hpp> | |
39 # include <boost/mpl/identity.hpp> | |
40 # include <boost/mpl/size.hpp> | |
41 # include <boost/mpl/at.hpp> | |
42 # include <boost/mpl/int.hpp> | |
43 # include <boost/mpl/next.hpp> | |
44 | |
45 namespace boost { namespace python { namespace detail { | |
46 | |
47 template <int N> | |
48 inline PyObject* get(mpl::int_<N>, PyObject* const& args_) | |
49 { | |
50 return PyTuple_GET_ITEM(args_,N); | |
51 } | |
52 | |
53 inline unsigned arity(PyObject* const& args_) | |
54 { | |
55 return PyTuple_GET_SIZE(args_); | |
56 } | |
57 | |
58 // This "result converter" is really just used as | |
59 // a dispatch tag to invoke(...), selecting the appropriate | |
60 // implementation | |
61 typedef int void_result_to_python; | |
62 | |
63 // Given a model of CallPolicies and a C++ result type, this | |
64 // metafunction selects the appropriate converter to use for | |
65 // converting the result to python. | |
66 template <class Policies, class Result> | |
67 struct select_result_converter | |
68 : mpl::eval_if< | |
69 is_same<Result,void> | |
70 , mpl::identity<void_result_to_python> | |
71 , mpl::apply1<typename Policies::result_converter,Result> | |
72 > | |
73 { | |
74 }; | |
75 | |
76 template <class ArgPackage, class ResultConverter> | |
77 inline ResultConverter create_result_converter( | |
78 ArgPackage const& args_ | |
79 , ResultConverter* | |
80 , converter::context_result_converter* | |
81 ) | |
82 { | |
83 return ResultConverter(args_); | |
84 } | |
85 | |
86 template <class ArgPackage, class ResultConverter> | |
87 inline ResultConverter create_result_converter( | |
88 ArgPackage const& | |
89 , ResultConverter* | |
90 , ... | |
91 ) | |
92 { | |
93 return ResultConverter(); | |
94 } | |
95 | |
96 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES | |
97 template <class ResultConverter> | |
98 struct converter_target_type | |
99 { | |
100 static PyTypeObject const *get_pytype() | |
101 { | |
102 return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype(); | |
103 } | |
104 }; | |
105 | |
106 template < > | |
107 struct converter_target_type <void_result_to_python > | |
108 { | |
109 static PyTypeObject const *get_pytype() | |
110 { | |
111 return 0; | |
112 } | |
113 }; | |
114 #endif | |
115 | |
116 | |
117 template <unsigned> struct caller_arity; | |
118 | |
119 template <class F, class CallPolicies, class Sig> | |
120 struct caller; | |
121 | |
122 # define BOOST_PYTHON_NEXT(init,name,n) \ | |
123 typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n; | |
124 | |
125 # define BOOST_PYTHON_ARG_CONVERTER(n) \ | |
126 BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \ | |
127 typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \ | |
128 c_t##n c##n(get(mpl::int_<n>(), inner_args)); \ | |
129 if (!c##n.convertible()) \ | |
130 return 0; | |
131 | |
132 # define BOOST_PP_ITERATION_PARAMS_1 \ | |
133 (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>)) | |
134 # include BOOST_PP_ITERATE() | |
135 | |
136 # undef BOOST_PYTHON_ARG_CONVERTER | |
137 # undef BOOST_PYTHON_NEXT | |
138 | |
139 // A metafunction returning the base class used for caller<class F, | |
140 // class ConverterGenerators, class CallPolicies, class Sig>. | |
141 template <class F, class CallPolicies, class Sig> | |
142 struct caller_base_select | |
143 { | |
144 enum { arity = mpl::size<Sig>::value - 1 }; | |
145 typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type; | |
146 }; | |
147 | |
148 // A function object type which wraps C++ objects as Python callable | |
149 // objects. | |
150 // | |
151 // Template Arguments: | |
152 // | |
153 // F - | |
154 // the C++ `function object' that will be called. Might | |
155 // actually be any data for which an appropriate invoke_tag() can | |
156 // be generated. invoke(...) takes care of the actual invocation syntax. | |
157 // | |
158 // CallPolicies - | |
159 // The precall, postcall, and what kind of resultconverter to | |
160 // generate for mpl::front<Sig>::type | |
161 // | |
162 // Sig - | |
163 // The `intended signature' of the function. An MPL sequence | |
164 // beginning with a result type and continuing with a list of | |
165 // argument types. | |
166 template <class F, class CallPolicies, class Sig> | |
167 struct caller | |
168 : caller_base_select<F,CallPolicies,Sig>::type | |
169 { | |
170 typedef typename caller_base_select< | |
171 F,CallPolicies,Sig | |
172 >::type base; | |
173 | |
174 typedef PyObject* result_type; | |
175 | |
176 caller(F f, CallPolicies p) : base(f,p) {} | |
177 | |
178 }; | |
179 | |
180 }}} // namespace boost::python::detail | |
181 | |
182 # endif // CALLER_DWA20021121_HPP | |
183 | |
184 #else | |
185 | |
186 # define N BOOST_PP_ITERATION() | |
187 | |
188 template <> | |
189 struct caller_arity<N> | |
190 { | |
191 template <class F, class Policies, class Sig> | |
192 struct impl | |
193 { | |
194 impl(F f, Policies p) : m_data(f,p) {} | |
195 | |
196 PyObject* operator()(PyObject* args_, PyObject*) // eliminate | |
197 // this | |
198 // trailing | |
199 // keyword dict | |
200 { | |
201 typedef typename mpl::begin<Sig>::type first; | |
202 typedef typename first::type result_t; | |
203 typedef typename select_result_converter<Policies, result_t>::type result_converter; | |
204 typedef typename Policies::argument_package argument_package; | |
205 | |
206 argument_package inner_args(args_); | |
207 | |
208 # if N | |
209 # define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) | |
210 # define BOOST_PP_LOCAL_LIMITS (0, N-1) | |
211 # include BOOST_PP_LOCAL_ITERATE() | |
212 # endif | |
213 // all converters have been checked. Now we can do the | |
214 // precall part of the policy | |
215 if (!m_data.second().precall(inner_args)) | |
216 return 0; | |
217 | |
218 PyObject* result = detail::invoke( | |
219 detail::invoke_tag<result_t,F>() | |
220 , create_result_converter(args_, (result_converter*)0, (result_converter*)0) | |
221 , m_data.first() | |
222 BOOST_PP_ENUM_TRAILING_PARAMS(N, c) | |
223 ); | |
224 | |
225 return m_data.second().postcall(inner_args, result); | |
226 } | |
227 | |
228 static unsigned min_arity() { return N; } | |
229 | |
230 static py_func_sig_info signature() | |
231 { | |
232 const signature_element * sig = detail::signature<Sig>::elements(); | |
233 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES | |
234 | |
235 typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype; | |
236 typedef typename select_result_converter<Policies, rtype>::type result_converter; | |
237 | |
238 static const signature_element ret = { | |
239 (boost::is_void<rtype>::value ? "void" : type_id<rtype>().name()) | |
240 , &detail::converter_target_type<result_converter>::get_pytype | |
241 , boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value | |
242 }; | |
243 py_func_sig_info res = {sig, &ret }; | |
244 #else | |
245 py_func_sig_info res = {sig, sig }; | |
246 #endif | |
247 | |
248 return res; | |
249 } | |
250 private: | |
251 compressed_pair<F,Policies> m_data; | |
252 }; | |
253 }; | |
254 | |
255 | |
256 | |
257 #endif // BOOST_PP_IS_ITERATING | |
258 | |
259 |