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