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