Chris@16
|
1 // Copyright Daniel Wallin 2006. Use, modification and distribution is
|
Chris@16
|
2 // subject to the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
4
|
Chris@16
|
5 #ifndef BOOST_PARAMETER_PYTHON_060209_HPP
|
Chris@16
|
6 # define BOOST_PARAMETER_PYTHON_060209_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # include <boost/mpl/vector.hpp>
|
Chris@16
|
9 # include <boost/mpl/fold.hpp>
|
Chris@16
|
10 # include <boost/mpl/prior.hpp>
|
Chris@16
|
11 # include <boost/mpl/shift_right.hpp>
|
Chris@16
|
12 # include <boost/mpl/shift_left.hpp>
|
Chris@16
|
13 # include <boost/mpl/bitand.hpp>
|
Chris@16
|
14 # include <boost/mpl/pair.hpp>
|
Chris@16
|
15 # include <boost/mpl/size.hpp>
|
Chris@16
|
16 # include <boost/mpl/push_back.hpp>
|
Chris@16
|
17 # include <boost/mpl/or.hpp>
|
Chris@16
|
18 # include <boost/mpl/count_if.hpp>
|
Chris@16
|
19 # include <boost/mpl/transform.hpp>
|
Chris@16
|
20 # include <boost/mpl/front.hpp>
|
Chris@16
|
21 # include <boost/mpl/iterator_range.hpp>
|
Chris@16
|
22 # include <boost/mpl/next.hpp>
|
Chris@16
|
23 # include <boost/mpl/begin_end.hpp>
|
Chris@16
|
24 # include <boost/mpl/not.hpp>
|
Chris@16
|
25 # include <boost/mpl/empty.hpp>
|
Chris@16
|
26 # include <boost/python/def.hpp>
|
Chris@16
|
27 # include <boost/python/make_constructor.hpp>
|
Chris@16
|
28 # include <boost/python/init.hpp>
|
Chris@16
|
29 # include <boost/python/to_python_converter.hpp>
|
Chris@16
|
30 # include <boost/parameter/aux_/maybe.hpp>
|
Chris@16
|
31 # include <boost/parameter/aux_/python/invoker.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 namespace boost { namespace parameter { namespace python
|
Chris@16
|
34 {
|
Chris@16
|
35 namespace python_ = boost::python;
|
Chris@16
|
36 }}}
|
Chris@16
|
37
|
Chris@16
|
38 namespace boost { namespace parameter { namespace python { namespace aux
|
Chris@16
|
39 {
|
Chris@16
|
40
|
Chris@16
|
41 inline PyObject* unspecified_type()
|
Chris@16
|
42 {
|
Chris@16
|
43 static PyTypeObject unspecified = {
|
Chris@16
|
44 PyObject_HEAD_INIT(NULL)
|
Chris@16
|
45 0, /* ob_size */
|
Chris@16
|
46 "Boost.Parameter.Unspecified", /* tp_name */
|
Chris@16
|
47 PyType_Type.tp_basicsize, /* tp_basicsize */
|
Chris@16
|
48 0, /* tp_itemsize */
|
Chris@16
|
49 0, /* tp_dealloc */
|
Chris@16
|
50 0, /* tp_print */
|
Chris@16
|
51 0, /* tp_getattr */
|
Chris@16
|
52 0, /* tp_setattr */
|
Chris@16
|
53 0, /* tp_compare */
|
Chris@16
|
54 0, /* tp_repr */
|
Chris@16
|
55 0, /* tp_as_number */
|
Chris@16
|
56 0, /* tp_as_sequence */
|
Chris@16
|
57 0, /* tp_as_mapping */
|
Chris@16
|
58 0, /* tp_hash */
|
Chris@16
|
59 0, /* tp_call */
|
Chris@16
|
60 0, /* tp_str */
|
Chris@16
|
61 0, /* tp_getattro */
|
Chris@16
|
62 0, /* tp_setattro */
|
Chris@16
|
63 0, /* tp_as_buffer */
|
Chris@16
|
64 Py_TPFLAGS_DEFAULT, /* tp_flags */
|
Chris@16
|
65 0, /* tp_doc */
|
Chris@16
|
66 };
|
Chris@16
|
67
|
Chris@16
|
68 if (unspecified.ob_type == 0)
|
Chris@16
|
69 {
|
Chris@16
|
70 unspecified.ob_type = &PyType_Type;
|
Chris@16
|
71 PyType_Ready(&unspecified);
|
Chris@16
|
72 }
|
Chris@16
|
73
|
Chris@16
|
74 return (PyObject*)&unspecified;
|
Chris@16
|
75 }
|
Chris@16
|
76
|
Chris@16
|
77 struct empty_tag {};
|
Chris@16
|
78
|
Chris@16
|
79 struct empty_tag_to_python
|
Chris@16
|
80 {
|
Chris@16
|
81 static PyObject* convert(empty_tag)
|
Chris@16
|
82 {
|
Chris@16
|
83 return python_::xincref(unspecified_type());
|
Chris@16
|
84 }
|
Chris@16
|
85 };
|
Chris@16
|
86
|
Chris@16
|
87 }}}} // namespace boost::parameter::python::aux
|
Chris@16
|
88
|
Chris@16
|
89 namespace boost { namespace python
|
Chris@16
|
90 {
|
Chris@16
|
91
|
Chris@16
|
92 // Converts a Python value to a maybe<T>
|
Chris@16
|
93 template <class T>
|
Chris@16
|
94 struct arg_from_python<parameter::aux::maybe<T> >
|
Chris@16
|
95 : arg_from_python<T>
|
Chris@16
|
96 {
|
Chris@16
|
97 arg_from_python(PyObject* p)
|
Chris@16
|
98 : arg_from_python<T>(p)
|
Chris@16
|
99 , empty(parameter::python::aux::unspecified_type() == p)
|
Chris@16
|
100 {}
|
Chris@16
|
101
|
Chris@16
|
102 bool convertible() const
|
Chris@16
|
103 {
|
Chris@16
|
104 return empty || arg_from_python<T>::convertible();
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 parameter::aux::maybe<T> operator()()
|
Chris@16
|
108 {
|
Chris@16
|
109 if (empty)
|
Chris@16
|
110 {
|
Chris@16
|
111 return parameter::aux::maybe<T>();
|
Chris@16
|
112 }
|
Chris@16
|
113 else
|
Chris@16
|
114 {
|
Chris@16
|
115 return parameter::aux::maybe<T>(
|
Chris@16
|
116 arg_from_python<T>::operator()()
|
Chris@16
|
117 );
|
Chris@16
|
118 }
|
Chris@16
|
119 }
|
Chris@16
|
120
|
Chris@16
|
121 bool empty;
|
Chris@16
|
122 };
|
Chris@16
|
123
|
Chris@16
|
124 }} // namespace boost::python
|
Chris@16
|
125
|
Chris@16
|
126 namespace boost { namespace parameter { namespace python {
|
Chris@16
|
127
|
Chris@16
|
128 namespace aux
|
Chris@16
|
129 {
|
Chris@16
|
130
|
Chris@16
|
131 template <class K>
|
Chris@16
|
132 struct is_optional
|
Chris@16
|
133 : mpl::not_<
|
Chris@16
|
134 mpl::or_<typename K::required, typename K::optimized_default>
|
Chris@16
|
135 >
|
Chris@16
|
136 {};
|
Chris@16
|
137
|
Chris@16
|
138 template <class K, class Required, class Optimized, class T>
|
Chris@16
|
139 struct arg_spec
|
Chris@16
|
140 {
|
Chris@16
|
141 typedef K keyword;
|
Chris@16
|
142 typedef Required required;
|
Chris@16
|
143 typedef T type;
|
Chris@16
|
144 typedef Optimized optimized_default;
|
Chris@16
|
145 };
|
Chris@16
|
146
|
Chris@16
|
147 template <class K, class T, class Optimized = mpl::false_>
|
Chris@16
|
148 struct make_arg_spec_impl
|
Chris@16
|
149 {
|
Chris@16
|
150 typedef arg_spec<
|
Chris@16
|
151 typename K::first, typename K::second, Optimized, T
|
Chris@16
|
152 > type;
|
Chris@16
|
153 };
|
Chris@16
|
154
|
Chris@16
|
155 template <class K, class T>
|
Chris@16
|
156 struct make_arg_spec_impl<K, T, typename K::third>
|
Chris@16
|
157 {
|
Chris@16
|
158 typedef arg_spec<
|
Chris@16
|
159 typename K::first, typename K::second, typename K::third, T
|
Chris@16
|
160 > type;
|
Chris@16
|
161 };
|
Chris@16
|
162
|
Chris@16
|
163 template <class K, class T>
|
Chris@16
|
164 struct make_arg_spec
|
Chris@16
|
165 : make_arg_spec_impl<K, T>
|
Chris@16
|
166 {
|
Chris@16
|
167 };
|
Chris@16
|
168
|
Chris@16
|
169 template <class Spec, class State>
|
Chris@16
|
170 struct combinations_op
|
Chris@16
|
171 {
|
Chris@16
|
172 typedef typename State::second bits;
|
Chris@16
|
173 typedef typename State::first result0;
|
Chris@16
|
174
|
Chris@16
|
175 typedef typename mpl::if_<
|
Chris@16
|
176 mpl::or_<
|
Chris@16
|
177 typename Spec::required
|
Chris@16
|
178 , typename Spec::optimized_default
|
Chris@16
|
179 , mpl::bitand_<bits, mpl::long_<1> >
|
Chris@16
|
180 >
|
Chris@16
|
181 , typename mpl::push_back<result0, Spec>::type
|
Chris@16
|
182 , result0
|
Chris@16
|
183 >::type result;
|
Chris@16
|
184
|
Chris@16
|
185 typedef typename mpl::if_<
|
Chris@16
|
186 mpl::or_<
|
Chris@16
|
187 typename Spec::required
|
Chris@16
|
188 , typename Spec::optimized_default
|
Chris@16
|
189 >
|
Chris@16
|
190 , bits
|
Chris@16
|
191 , typename mpl::shift_right<bits, mpl::long_<1> >::type
|
Chris@16
|
192 >::type next_bits;
|
Chris@16
|
193
|
Chris@16
|
194 typedef mpl::pair<
|
Chris@16
|
195 result
|
Chris@16
|
196 , next_bits
|
Chris@16
|
197 > type;
|
Chris@16
|
198 };
|
Chris@16
|
199
|
Chris@16
|
200 // Used as start value in the recursive arg() composition below.
|
Chris@16
|
201 struct no_keywords
|
Chris@16
|
202 {
|
Chris@16
|
203 template <class T>
|
Chris@16
|
204 T const& operator,(T const& x) const
|
Chris@16
|
205 {
|
Chris@16
|
206 return x;
|
Chris@16
|
207 }
|
Chris@16
|
208 };
|
Chris@16
|
209
|
Chris@16
|
210 template <class Def, class F, class Iter, class End, class Keywords>
|
Chris@16
|
211 void def_combination_aux0(
|
Chris@16
|
212 Def def, F f, Iter, End, Keywords const& keywords, mpl::false_)
|
Chris@16
|
213 {
|
Chris@16
|
214 typedef typename mpl::deref<Iter>::type spec;
|
Chris@16
|
215 typedef typename spec::keyword kw;
|
Chris@16
|
216
|
Chris@16
|
217 def_combination_aux(
|
Chris@16
|
218 def, f, typename mpl::next<Iter>::type(), End()
|
Chris@16
|
219 , (
|
Chris@16
|
220 keywords, boost::python::arg(kw::keyword_name())
|
Chris@16
|
221 )
|
Chris@16
|
222 );
|
Chris@16
|
223 }
|
Chris@16
|
224
|
Chris@16
|
225 template <class Def, class F, class Iter, class End, class Keywords>
|
Chris@16
|
226 void def_combination_aux0(
|
Chris@16
|
227 Def def, F f, Iter, End, Keywords const& keywords, mpl::true_)
|
Chris@16
|
228 {
|
Chris@16
|
229 typedef typename mpl::deref<Iter>::type spec;
|
Chris@16
|
230 typedef typename spec::keyword kw;
|
Chris@16
|
231
|
Chris@16
|
232 def_combination_aux(
|
Chris@16
|
233 def, f, typename mpl::next<Iter>::type(), End()
|
Chris@16
|
234 , (
|
Chris@16
|
235 keywords, boost::python::arg(kw::keyword_name()) = empty_tag()
|
Chris@16
|
236 )
|
Chris@16
|
237 );
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240 inline void initialize_converter()
|
Chris@16
|
241 {
|
Chris@16
|
242 static python_::to_python_converter<empty_tag, empty_tag_to_python> x;
|
Chris@16
|
243 }
|
Chris@16
|
244
|
Chris@16
|
245 template <class Def, class F, class Iter, class End, class Keywords>
|
Chris@16
|
246 void def_combination_aux(
|
Chris@16
|
247 Def def, F f, Iter, End, Keywords const& keywords)
|
Chris@16
|
248 {
|
Chris@16
|
249 typedef typename mpl::deref<Iter>::type spec;
|
Chris@16
|
250
|
Chris@16
|
251 typedef typename mpl::and_<
|
Chris@16
|
252 typename spec::optimized_default
|
Chris@16
|
253 , mpl::not_<typename spec::required>
|
Chris@16
|
254 >::type optimized_default;
|
Chris@16
|
255
|
Chris@16
|
256 def_combination_aux0(
|
Chris@16
|
257 def, f, Iter(), End(), keywords, optimized_default()
|
Chris@16
|
258 );
|
Chris@16
|
259 }
|
Chris@16
|
260
|
Chris@16
|
261 template <class Def, class F, class End, class Keywords>
|
Chris@16
|
262 void def_combination_aux(
|
Chris@16
|
263 Def def, F f, End, End, Keywords const& keywords)
|
Chris@16
|
264 {
|
Chris@16
|
265 def(f, keywords);
|
Chris@16
|
266 }
|
Chris@16
|
267
|
Chris@16
|
268 template <class Def, class F, class End>
|
Chris@16
|
269 void def_combination_aux(
|
Chris@16
|
270 Def def, F f, End, End, no_keywords const&)
|
Chris@16
|
271 {
|
Chris@16
|
272 def(f);
|
Chris@16
|
273 }
|
Chris@16
|
274
|
Chris@16
|
275 template <
|
Chris@16
|
276 class Def, class Specs, class Bits, class Invoker
|
Chris@16
|
277 >
|
Chris@16
|
278 void def_combination(
|
Chris@16
|
279 Def def, Specs*, Bits, Invoker*)
|
Chris@16
|
280 {
|
Chris@16
|
281 typedef typename mpl::fold<
|
Chris@16
|
282 Specs
|
Chris@16
|
283 , mpl::pair<mpl::vector0<>, Bits>
|
Chris@16
|
284 , combinations_op<mpl::_2, mpl::_1>
|
Chris@16
|
285 >::type combination0;
|
Chris@16
|
286
|
Chris@16
|
287 typedef typename combination0::first combination;
|
Chris@16
|
288
|
Chris@16
|
289 typedef typename mpl::apply_wrap1<
|
Chris@16
|
290 Invoker, combination
|
Chris@16
|
291 >::type invoker;
|
Chris@16
|
292
|
Chris@16
|
293 def_combination_aux(
|
Chris@16
|
294 def
|
Chris@16
|
295 , &invoker::execute
|
Chris@16
|
296 , typename mpl::begin<combination>::type()
|
Chris@16
|
297 , typename mpl::end<combination>::type()
|
Chris@16
|
298 , no_keywords()
|
Chris@16
|
299 );
|
Chris@16
|
300 }
|
Chris@16
|
301
|
Chris@16
|
302 template <
|
Chris@16
|
303 class Def, class Specs, class Bits, class End, class Invoker
|
Chris@16
|
304 >
|
Chris@16
|
305 void def_combinations(
|
Chris@16
|
306 Def def, Specs*, Bits, End, Invoker*)
|
Chris@16
|
307 {
|
Chris@16
|
308 initialize_converter();
|
Chris@16
|
309
|
Chris@16
|
310 def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
|
Chris@16
|
311
|
Chris@16
|
312 def_combinations(
|
Chris@16
|
313 def
|
Chris@16
|
314 , (Specs*)0
|
Chris@16
|
315 , mpl::long_<Bits::value + 1>()
|
Chris@16
|
316 , End()
|
Chris@16
|
317 , (Invoker*)0
|
Chris@16
|
318 );
|
Chris@16
|
319 }
|
Chris@16
|
320
|
Chris@16
|
321 template <
|
Chris@16
|
322 class Def, class Specs, class End, class Invoker
|
Chris@16
|
323 >
|
Chris@16
|
324 void def_combinations(
|
Chris@16
|
325 Def, Specs*, End, End, Invoker*)
|
Chris@16
|
326 {}
|
Chris@16
|
327
|
Chris@16
|
328 struct not_specified {};
|
Chris@16
|
329
|
Chris@16
|
330 template <class CallPolicies>
|
Chris@16
|
331 struct call_policies_as_options
|
Chris@16
|
332 {
|
Chris@16
|
333 call_policies_as_options(CallPolicies const& call_policies)
|
Chris@16
|
334 : call_policies(call_policies)
|
Chris@16
|
335 {}
|
Chris@16
|
336
|
Chris@16
|
337 CallPolicies const& policies() const
|
Chris@16
|
338 {
|
Chris@16
|
339 return call_policies;
|
Chris@16
|
340 }
|
Chris@16
|
341
|
Chris@16
|
342 char const* doc() const
|
Chris@16
|
343 {
|
Chris@16
|
344 return 0;
|
Chris@16
|
345 }
|
Chris@16
|
346
|
Chris@16
|
347 CallPolicies call_policies;
|
Chris@16
|
348 };
|
Chris@16
|
349
|
Chris@16
|
350 template <class Class, class Options = not_specified>
|
Chris@16
|
351 struct def_class
|
Chris@16
|
352 {
|
Chris@16
|
353 def_class(Class& cl, char const* name, Options options = Options())
|
Chris@16
|
354 : cl(cl)
|
Chris@16
|
355 , name(name)
|
Chris@16
|
356 , options(options)
|
Chris@16
|
357 {}
|
Chris@16
|
358
|
Chris@16
|
359 template <class F>
|
Chris@16
|
360 void def(F f, not_specified const*) const
|
Chris@16
|
361 {
|
Chris@16
|
362 cl.def(name, f);
|
Chris@16
|
363 }
|
Chris@16
|
364
|
Chris@16
|
365 template <class F>
|
Chris@16
|
366 void def(F f, void const*) const
|
Chris@16
|
367 {
|
Chris@16
|
368 cl.def(name, f, options.doc(), options.policies());
|
Chris@16
|
369 }
|
Chris@16
|
370
|
Chris@16
|
371 template <class F>
|
Chris@16
|
372 void operator()(F f) const
|
Chris@16
|
373 {
|
Chris@16
|
374 this->def(f, &options);
|
Chris@16
|
375 }
|
Chris@16
|
376
|
Chris@16
|
377 template <class F, class Keywords>
|
Chris@16
|
378 void def(F f, Keywords const& keywords, not_specified const*) const
|
Chris@16
|
379 {
|
Chris@16
|
380 cl.def(name, f, keywords);
|
Chris@16
|
381 }
|
Chris@16
|
382
|
Chris@16
|
383 template <class F, class Keywords>
|
Chris@16
|
384 void def(F f, Keywords const& keywords, void const*) const
|
Chris@16
|
385 {
|
Chris@16
|
386 cl.def(name, f, keywords, options.doc(), options.policies());
|
Chris@16
|
387 }
|
Chris@16
|
388
|
Chris@16
|
389 template <class F, class Keywords>
|
Chris@16
|
390 void operator()(F f, Keywords const& keywords) const
|
Chris@16
|
391 {
|
Chris@16
|
392 this->def(f, keywords, &options);
|
Chris@16
|
393 }
|
Chris@16
|
394
|
Chris@16
|
395 Class& cl;
|
Chris@16
|
396 char const* name;
|
Chris@16
|
397 Options options;
|
Chris@16
|
398 };
|
Chris@16
|
399
|
Chris@16
|
400 template <class Class, class CallPolicies = boost::python::default_call_policies>
|
Chris@16
|
401 struct def_init
|
Chris@16
|
402 {
|
Chris@16
|
403 def_init(Class& cl, CallPolicies call_policies = CallPolicies())
|
Chris@16
|
404 : cl(cl)
|
Chris@16
|
405 , call_policies(call_policies)
|
Chris@16
|
406 {}
|
Chris@16
|
407
|
Chris@16
|
408 template <class F>
|
Chris@16
|
409 void operator()(F f) const
|
Chris@16
|
410 {
|
Chris@16
|
411 cl.def(
|
Chris@16
|
412 "__init__"
|
Chris@16
|
413 , boost::python::make_constructor(f, call_policies)
|
Chris@16
|
414 );
|
Chris@16
|
415 }
|
Chris@16
|
416
|
Chris@16
|
417 template <class F, class Keywords>
|
Chris@16
|
418 void operator()(F f, Keywords const& keywords) const
|
Chris@16
|
419 {
|
Chris@16
|
420 cl.def(
|
Chris@16
|
421 "__init__"
|
Chris@16
|
422 , boost::python::make_constructor(f, call_policies, keywords)
|
Chris@16
|
423 );
|
Chris@16
|
424 }
|
Chris@16
|
425
|
Chris@16
|
426 Class& cl;
|
Chris@16
|
427 CallPolicies call_policies;
|
Chris@16
|
428 };
|
Chris@16
|
429
|
Chris@16
|
430 struct def_function
|
Chris@16
|
431 {
|
Chris@16
|
432 def_function(char const* name)
|
Chris@16
|
433 : name(name)
|
Chris@16
|
434 {}
|
Chris@16
|
435
|
Chris@16
|
436 template <class F>
|
Chris@16
|
437 void operator()(F f) const
|
Chris@16
|
438 {
|
Chris@16
|
439 boost::python::def(name, f);
|
Chris@16
|
440 }
|
Chris@16
|
441
|
Chris@16
|
442 template <class F, class Keywords>
|
Chris@16
|
443 void operator()(F f, Keywords const& keywords) const
|
Chris@16
|
444 {
|
Chris@16
|
445 boost::python::def(name, f, keywords);
|
Chris@16
|
446 }
|
Chris@16
|
447
|
Chris@16
|
448 char const* name;
|
Chris@16
|
449 };
|
Chris@16
|
450
|
Chris@16
|
451 } // namespace aux
|
Chris@16
|
452
|
Chris@16
|
453 template <class M, class Signature>
|
Chris@16
|
454 void def(char const* name, Signature)
|
Chris@16
|
455 {
|
Chris@16
|
456 typedef mpl::iterator_range<
|
Chris@16
|
457 typename mpl::next<
|
Chris@16
|
458 typename mpl::begin<Signature>::type
|
Chris@16
|
459 >::type
|
Chris@16
|
460 , typename mpl::end<Signature>::type
|
Chris@16
|
461 > arg_types;
|
Chris@16
|
462
|
Chris@16
|
463 typedef typename mpl::transform<
|
Chris@16
|
464 typename M::keywords
|
Chris@16
|
465 , arg_types
|
Chris@16
|
466 , aux::make_arg_spec<mpl::_1, mpl::_2>
|
Chris@16
|
467 , mpl::back_inserter<mpl::vector0<> >
|
Chris@16
|
468 >::type arg_specs;
|
Chris@16
|
469
|
Chris@16
|
470 typedef typename mpl::count_if<
|
Chris@16
|
471 arg_specs
|
Chris@16
|
472 , aux::is_optional<mpl::_1>
|
Chris@16
|
473 >::type optional_arity;
|
Chris@16
|
474
|
Chris@16
|
475 typedef typename mpl::front<Signature>::type result_type;
|
Chris@16
|
476 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
Chris@16
|
477
|
Chris@16
|
478 aux::def_combinations(
|
Chris@16
|
479 aux::def_function(name)
|
Chris@16
|
480 , (arg_specs*)0
|
Chris@16
|
481 , mpl::long_<0>()
|
Chris@16
|
482 , mpl::long_<upper::value>()
|
Chris@16
|
483 , (aux::make_invoker<M, result_type>*)0
|
Chris@16
|
484 );
|
Chris@16
|
485 }
|
Chris@16
|
486
|
Chris@16
|
487 template <class M, class Class, class Signature>
|
Chris@16
|
488 void def(Class& cl, char const* name, Signature)
|
Chris@16
|
489 {
|
Chris@16
|
490 typedef mpl::iterator_range<
|
Chris@16
|
491 typename mpl::next<
|
Chris@16
|
492 typename mpl::begin<Signature>::type
|
Chris@16
|
493 >::type
|
Chris@16
|
494 , typename mpl::end<Signature>::type
|
Chris@16
|
495 > arg_types;
|
Chris@16
|
496
|
Chris@16
|
497 typedef typename mpl::transform<
|
Chris@16
|
498 typename M::keywords
|
Chris@16
|
499 , arg_types
|
Chris@16
|
500 , aux::make_arg_spec<mpl::_1, mpl::_2>
|
Chris@16
|
501 , mpl::back_inserter<mpl::vector0<> >
|
Chris@16
|
502 >::type arg_specs;
|
Chris@16
|
503
|
Chris@16
|
504 typedef typename mpl::count_if<
|
Chris@16
|
505 arg_specs
|
Chris@16
|
506 , aux::is_optional<mpl::_1>
|
Chris@16
|
507 >::type optional_arity;
|
Chris@16
|
508
|
Chris@16
|
509 typedef typename mpl::front<Signature>::type result_type;
|
Chris@16
|
510 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
Chris@16
|
511
|
Chris@16
|
512 aux::def_combinations(
|
Chris@16
|
513 aux::def_class<Class>(cl, name)
|
Chris@16
|
514 , (arg_specs*)0
|
Chris@16
|
515 , mpl::long_<0>()
|
Chris@16
|
516 , mpl::long_<upper::value>()
|
Chris@16
|
517 , (aux::make_invoker<M, result_type>*)0
|
Chris@16
|
518 );
|
Chris@16
|
519 }
|
Chris@16
|
520
|
Chris@16
|
521 namespace aux
|
Chris@16
|
522 {
|
Chris@16
|
523
|
Chris@16
|
524 template <class K>
|
Chris@16
|
525 struct keyword
|
Chris@16
|
526 {
|
Chris@16
|
527 typedef K type;
|
Chris@16
|
528 };
|
Chris@16
|
529
|
Chris@16
|
530 template <class K>
|
Chris@16
|
531 struct keyword<K*>
|
Chris@16
|
532 {
|
Chris@16
|
533 typedef K type;
|
Chris@16
|
534 };
|
Chris@16
|
535
|
Chris@16
|
536 template <class K>
|
Chris@16
|
537 struct keyword<K**>
|
Chris@16
|
538 {
|
Chris@16
|
539 typedef K type;
|
Chris@16
|
540 };
|
Chris@16
|
541
|
Chris@16
|
542 template <class K>
|
Chris@16
|
543 struct required
|
Chris@16
|
544 {
|
Chris@16
|
545 typedef mpl::true_ type;
|
Chris@16
|
546 };
|
Chris@16
|
547
|
Chris@16
|
548 template <class K>
|
Chris@16
|
549 struct required<K*>
|
Chris@16
|
550 {
|
Chris@16
|
551 typedef mpl::false_ type;
|
Chris@16
|
552 };
|
Chris@16
|
553
|
Chris@16
|
554 template <class K>
|
Chris@16
|
555 struct optimized
|
Chris@16
|
556 {
|
Chris@16
|
557 typedef mpl::true_ type;
|
Chris@16
|
558 };
|
Chris@16
|
559
|
Chris@16
|
560 template <class K>
|
Chris@16
|
561 struct optimized<K**>
|
Chris@16
|
562 {
|
Chris@16
|
563 typedef mpl::false_ type;
|
Chris@16
|
564 };
|
Chris@16
|
565
|
Chris@16
|
566 template <class T>
|
Chris@16
|
567 struct make_kw_spec;
|
Chris@16
|
568
|
Chris@16
|
569 template <class K, class T>
|
Chris@16
|
570 struct make_kw_spec<K(T)>
|
Chris@16
|
571 {
|
Chris@16
|
572 typedef arg_spec<
|
Chris@16
|
573 typename keyword<K>::type
|
Chris@16
|
574 , typename required<K>::type
|
Chris@16
|
575 , typename optimized<K>::type
|
Chris@16
|
576 , T
|
Chris@16
|
577 > type;
|
Chris@16
|
578 };
|
Chris@16
|
579
|
Chris@16
|
580 } // namespace aux
|
Chris@16
|
581
|
Chris@16
|
582 template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
|
Chris@16
|
583 struct init
|
Chris@16
|
584 : boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
|
Chris@16
|
585 {
|
Chris@16
|
586 init(CallPolicies call_policies = CallPolicies())
|
Chris@16
|
587 : call_policies(call_policies)
|
Chris@16
|
588 {}
|
Chris@16
|
589
|
Chris@16
|
590 template <class CallPolicies1>
|
Chris@16
|
591 init<ParameterSpecs, CallPolicies1>
|
Chris@16
|
592 operator[](CallPolicies1 const& call_policies) const
|
Chris@16
|
593 {
|
Chris@16
|
594 return init<ParameterSpecs, CallPolicies1>(call_policies);
|
Chris@16
|
595 }
|
Chris@16
|
596
|
Chris@16
|
597 template <class Class>
|
Chris@16
|
598 void visit_aux(Class& cl, mpl::true_) const
|
Chris@16
|
599 {
|
Chris@16
|
600 cl.def(boost::python::init<>()[call_policies]);
|
Chris@16
|
601 }
|
Chris@16
|
602
|
Chris@16
|
603 template <class Class>
|
Chris@16
|
604 void visit_aux(Class& cl, mpl::false_) const
|
Chris@16
|
605 {
|
Chris@16
|
606 typedef typename mpl::transform<
|
Chris@16
|
607 ParameterSpecs
|
Chris@16
|
608 , aux::make_kw_spec<mpl::_>
|
Chris@16
|
609 , mpl::back_inserter<mpl::vector0<> >
|
Chris@16
|
610 >::type arg_specs;
|
Chris@16
|
611
|
Chris@16
|
612 typedef typename mpl::count_if<
|
Chris@16
|
613 arg_specs
|
Chris@16
|
614 , aux::is_optional<mpl::_>
|
Chris@16
|
615 >::type optional_arity;
|
Chris@16
|
616
|
Chris@16
|
617 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
Chris@16
|
618
|
Chris@16
|
619 aux::def_combinations(
|
Chris@16
|
620 aux::def_init<Class, CallPolicies>(cl, call_policies)
|
Chris@16
|
621 , (arg_specs*)0
|
Chris@16
|
622 , mpl::long_<0>()
|
Chris@16
|
623 , mpl::long_<upper::value>()
|
Chris@16
|
624 , (aux::make_init_invoker<typename Class::wrapped_type>*)0
|
Chris@16
|
625 );
|
Chris@16
|
626 }
|
Chris@16
|
627
|
Chris@16
|
628 template <class Class>
|
Chris@16
|
629 void visit(Class& cl) const
|
Chris@16
|
630 {
|
Chris@16
|
631 visit_aux(cl, mpl::empty<ParameterSpecs>());
|
Chris@16
|
632 }
|
Chris@16
|
633
|
Chris@16
|
634 CallPolicies call_policies;
|
Chris@16
|
635 };
|
Chris@16
|
636
|
Chris@16
|
637 template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
|
Chris@16
|
638 struct call
|
Chris@16
|
639 : boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
|
Chris@16
|
640 {
|
Chris@16
|
641 call(CallPolicies const& call_policies = CallPolicies())
|
Chris@16
|
642 : call_policies(call_policies)
|
Chris@16
|
643 {}
|
Chris@16
|
644
|
Chris@16
|
645 template <class CallPolicies1>
|
Chris@16
|
646 call<ParameterSpecs, CallPolicies1>
|
Chris@16
|
647 operator[](CallPolicies1 const& call_policies) const
|
Chris@16
|
648 {
|
Chris@16
|
649 return call<ParameterSpecs, CallPolicies1>(call_policies);
|
Chris@16
|
650 }
|
Chris@16
|
651
|
Chris@16
|
652 template <class Class>
|
Chris@16
|
653 void visit(Class& cl) const
|
Chris@16
|
654 {
|
Chris@16
|
655 typedef mpl::iterator_range<
|
Chris@16
|
656 typename mpl::next<
|
Chris@16
|
657 typename mpl::begin<ParameterSpecs>::type
|
Chris@16
|
658 >::type
|
Chris@16
|
659 , typename mpl::end<ParameterSpecs>::type
|
Chris@16
|
660 > arg_types;
|
Chris@16
|
661
|
Chris@16
|
662 typedef typename mpl::front<ParameterSpecs>::type result_type;
|
Chris@16
|
663
|
Chris@16
|
664 typedef typename mpl::transform<
|
Chris@16
|
665 arg_types
|
Chris@16
|
666 , aux::make_kw_spec<mpl::_>
|
Chris@16
|
667 , mpl::back_inserter<mpl::vector0<> >
|
Chris@16
|
668 >::type arg_specs;
|
Chris@16
|
669
|
Chris@16
|
670 typedef typename mpl::count_if<
|
Chris@16
|
671 arg_specs
|
Chris@16
|
672 , aux::is_optional<mpl::_>
|
Chris@16
|
673 >::type optional_arity;
|
Chris@16
|
674
|
Chris@16
|
675 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
Chris@16
|
676
|
Chris@16
|
677 typedef aux::call_policies_as_options<CallPolicies> options;
|
Chris@16
|
678
|
Chris@16
|
679 aux::def_combinations(
|
Chris@16
|
680 aux::def_class<Class, options>(cl, "__call__", options(call_policies))
|
Chris@16
|
681 , (arg_specs*)0
|
Chris@16
|
682 , mpl::long_<0>()
|
Chris@16
|
683 , mpl::long_<upper::value>()
|
Chris@16
|
684 , (aux::make_call_invoker<typename Class::wrapped_type, result_type>*)0
|
Chris@16
|
685 );
|
Chris@16
|
686 }
|
Chris@16
|
687
|
Chris@16
|
688 CallPolicies call_policies;
|
Chris@16
|
689 };
|
Chris@16
|
690
|
Chris@16
|
691 template <class Fwd, class ParameterSpecs>
|
Chris@16
|
692 struct function
|
Chris@16
|
693 : boost::python::def_visitor<function<Fwd, ParameterSpecs> >
|
Chris@16
|
694 {
|
Chris@16
|
695 template <class Class, class Options>
|
Chris@16
|
696 void visit(Class& cl, char const* name, Options const& options) const
|
Chris@16
|
697 {
|
Chris@16
|
698 typedef mpl::iterator_range<
|
Chris@16
|
699 typename mpl::next<
|
Chris@16
|
700 typename mpl::begin<ParameterSpecs>::type
|
Chris@16
|
701 >::type
|
Chris@16
|
702 , typename mpl::end<ParameterSpecs>::type
|
Chris@16
|
703 > arg_types;
|
Chris@16
|
704
|
Chris@16
|
705 typedef typename mpl::front<ParameterSpecs>::type result_type;
|
Chris@16
|
706
|
Chris@16
|
707 typedef typename mpl::transform<
|
Chris@16
|
708 arg_types
|
Chris@16
|
709 , aux::make_kw_spec<mpl::_>
|
Chris@16
|
710 , mpl::back_inserter<mpl::vector0<> >
|
Chris@16
|
711 >::type arg_specs;
|
Chris@16
|
712
|
Chris@16
|
713 typedef typename mpl::count_if<
|
Chris@16
|
714 arg_specs
|
Chris@16
|
715 , aux::is_optional<mpl::_>
|
Chris@16
|
716 >::type optional_arity;
|
Chris@16
|
717
|
Chris@16
|
718 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
|
Chris@16
|
719
|
Chris@16
|
720 aux::def_combinations(
|
Chris@16
|
721 aux::def_class<Class, Options>(cl, name, options)
|
Chris@16
|
722 , (arg_specs*)0
|
Chris@16
|
723 , mpl::long_<0>()
|
Chris@16
|
724 , mpl::long_<upper::value>()
|
Chris@16
|
725 , (aux::make_member_invoker<
|
Chris@16
|
726 Fwd, result_type, typename Class::wrapped_type
|
Chris@16
|
727 >*)0
|
Chris@16
|
728 );
|
Chris@16
|
729 }
|
Chris@16
|
730 };
|
Chris@16
|
731
|
Chris@16
|
732 }}} // namespace boost::parameter::python
|
Chris@16
|
733
|
Chris@16
|
734 #endif // BOOST_PARAMETER_PYTHON_060209_HPP
|
Chris@16
|
735
|