]>
Commit | Line | Data |
---|---|---|
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 |