Pack required boost code together.
[xy_vsfilter.git] / src / thirdparty / boost_1_47_0 / boost / parameter / python.hpp
blob02247aaf11c9290c6fdc36cdcf73ed528fc71277
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)
5 #ifndef BOOST_PARAMETER_PYTHON_060209_HPP
6 # define BOOST_PARAMETER_PYTHON_060209_HPP
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>
33 namespace boost { namespace parameter { namespace python
35 namespace python_ = boost::python;
36 }}}
38 namespace boost { namespace parameter { namespace python { namespace aux
41 inline PyObject* unspecified_type()
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 */
68 if (unspecified.ob_type == 0)
70 unspecified.ob_type = &PyType_Type;
71 PyType_Ready(&unspecified);
74 return (PyObject*)&unspecified;
77 struct empty_tag {};
79 struct empty_tag_to_python
81 static PyObject* convert(empty_tag)
83 return python_::xincref(unspecified_type());
87 }}}} // namespace boost::parameter::python::aux
89 namespace boost { namespace python
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>
97 arg_from_python(PyObject* p)
98 : arg_from_python<T>(p)
99 , empty(parameter::python::aux::unspecified_type() == p)
102 bool convertible() const
104 return empty || arg_from_python<T>::convertible();
107 parameter::aux::maybe<T> operator()()
109 if (empty)
111 return parameter::aux::maybe<T>();
113 else
115 return parameter::aux::maybe<T>(
116 arg_from_python<T>::operator()()
121 bool empty;
124 }} // namespace boost::python
126 namespace boost { namespace parameter { namespace python {
128 namespace aux
131 template <class K>
132 struct is_optional
133 : mpl::not_<
134 mpl::or_<typename K::required, typename K::optimized_default>
138 template <class K, class Required, class Optimized, class T>
139 struct arg_spec
141 typedef K keyword;
142 typedef Required required;
143 typedef T type;
144 typedef Optimized optimized_default;
147 template <class K, class T, class Optimized = mpl::false_>
148 struct make_arg_spec_impl
150 typedef arg_spec<
151 typename K::first, typename K::second, Optimized, T
152 > type;
155 template <class K, class T>
156 struct make_arg_spec_impl<K, T, typename K::third>
158 typedef arg_spec<
159 typename K::first, typename K::second, typename K::third, T
160 > type;
163 template <class K, class T>
164 struct make_arg_spec
165 : make_arg_spec_impl<K, T>
169 template <class Spec, class State>
170 struct combinations_op
172 typedef typename State::second bits;
173 typedef typename State::first result0;
175 typedef typename mpl::if_<
176 mpl::or_<
177 typename Spec::required
178 , typename Spec::optimized_default
179 , mpl::bitand_<bits, mpl::long_<1> >
181 , typename mpl::push_back<result0, Spec>::type
182 , result0
183 >::type result;
185 typedef typename mpl::if_<
186 mpl::or_<
187 typename Spec::required
188 , typename Spec::optimized_default
190 , bits
191 , typename mpl::shift_right<bits, mpl::long_<1> >::type
192 >::type next_bits;
194 typedef mpl::pair<
195 result
196 , next_bits
197 > type;
200 // Used as start value in the recursive arg() composition below.
201 struct no_keywords
203 template <class T>
204 T const& operator,(T const& x) const
206 return x;
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_)
214 typedef typename mpl::deref<Iter>::type spec;
215 typedef typename spec::keyword kw;
217 def_combination_aux(
218 def, f, typename mpl::next<Iter>::type(), End()
220 keywords, boost::python::arg(kw::keyword_name())
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_)
229 typedef typename mpl::deref<Iter>::type spec;
230 typedef typename spec::keyword kw;
232 def_combination_aux(
233 def, f, typename mpl::next<Iter>::type(), End()
235 keywords, boost::python::arg(kw::keyword_name()) = empty_tag()
240 inline void initialize_converter()
242 static python_::to_python_converter<empty_tag, empty_tag_to_python> x;
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)
249 typedef typename mpl::deref<Iter>::type spec;
251 typedef typename mpl::and_<
252 typename spec::optimized_default
253 , mpl::not_<typename spec::required>
254 >::type optimized_default;
256 def_combination_aux0(
257 def, f, Iter(), End(), keywords, optimized_default()
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)
265 def(f, keywords);
268 template <class Def, class F, class End>
269 void def_combination_aux(
270 Def def, F f, End, End, no_keywords const&)
272 def(f);
275 template <
276 class Def, class Specs, class Bits, class Invoker
278 void def_combination(
279 Def def, Specs*, Bits, Invoker*)
281 typedef typename mpl::fold<
282 Specs
283 , mpl::pair<mpl::vector0<>, Bits>
284 , combinations_op<mpl::_2, mpl::_1>
285 >::type combination0;
287 typedef typename combination0::first combination;
289 typedef typename mpl::apply_wrap1<
290 Invoker, combination
291 >::type invoker;
293 def_combination_aux(
295 , &invoker::execute
296 , typename mpl::begin<combination>::type()
297 , typename mpl::end<combination>::type()
298 , no_keywords()
302 template <
303 class Def, class Specs, class Bits, class End, class Invoker
305 void def_combinations(
306 Def def, Specs*, Bits, End, Invoker*)
308 initialize_converter();
310 def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
312 def_combinations(
314 , (Specs*)0
315 , mpl::long_<Bits::value + 1>()
316 , End()
317 , (Invoker*)0
321 template <
322 class Def, class Specs, class End, class Invoker
324 void def_combinations(
325 Def, Specs*, End, End, Invoker*)
328 struct not_specified {};
330 template <class CallPolicies>
331 struct call_policies_as_options
333 call_policies_as_options(CallPolicies const& call_policies)
334 : call_policies(call_policies)
337 CallPolicies const& policies() const
339 return call_policies;
342 char const* doc() const
344 return 0;
347 CallPolicies call_policies;
350 template <class Class, class Options = not_specified>
351 struct def_class
353 def_class(Class& cl, char const* name, Options options = Options())
354 : cl(cl)
355 , name(name)
356 , options(options)
359 template <class F>
360 void def(F f, not_specified const*) const
362 cl.def(name, f);
365 template <class F>
366 void def(F f, void const*) const
368 cl.def(name, f, options.doc(), options.policies());
371 template <class F>
372 void operator()(F f) const
374 this->def(f, &options);
377 template <class F, class Keywords>
378 void def(F f, Keywords const& keywords, not_specified const*) const
380 cl.def(name, f, keywords);
383 template <class F, class Keywords>
384 void def(F f, Keywords const& keywords, void const*) const
386 cl.def(name, f, keywords, options.doc(), options.policies());
389 template <class F, class Keywords>
390 void operator()(F f, Keywords const& keywords) const
392 this->def(f, keywords, &options);
395 Class& cl;
396 char const* name;
397 Options options;
400 template <class Class, class CallPolicies = boost::python::default_call_policies>
401 struct def_init
403 def_init(Class& cl, CallPolicies call_policies = CallPolicies())
404 : cl(cl)
405 , call_policies(call_policies)
408 template <class F>
409 void operator()(F f) const
411 cl.def(
412 "__init__"
413 , boost::python::make_constructor(f, call_policies)
417 template <class F, class Keywords>
418 void operator()(F f, Keywords const& keywords) const
420 cl.def(
421 "__init__"
422 , boost::python::make_constructor(f, call_policies, keywords)
426 Class& cl;
427 CallPolicies call_policies;
430 struct def_function
432 def_function(char const* name)
433 : name(name)
436 template <class F>
437 void operator()(F f) const
439 boost::python::def(name, f);
442 template <class F, class Keywords>
443 void operator()(F f, Keywords const& keywords) const
445 boost::python::def(name, f, keywords);
448 char const* name;
451 } // namespace aux
453 template <class M, class Signature>
454 void def(char const* name, Signature)
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;
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;
470 typedef typename mpl::count_if<
471 arg_specs
472 , aux::is_optional<mpl::_1>
473 >::type optional_arity;
475 typedef typename mpl::front<Signature>::type result_type;
476 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
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
487 template <class M, class Class, class Signature>
488 void def(Class& cl, char const* name, Signature)
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;
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;
504 typedef typename mpl::count_if<
505 arg_specs
506 , aux::is_optional<mpl::_1>
507 >::type optional_arity;
509 typedef typename mpl::front<Signature>::type result_type;
510 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
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
521 namespace aux
524 template <class K>
525 struct keyword
527 typedef K type;
530 template <class K>
531 struct keyword<K*>
533 typedef K type;
536 template <class K>
537 struct keyword<K**>
539 typedef K type;
542 template <class K>
543 struct required
545 typedef mpl::true_ type;
548 template <class K>
549 struct required<K*>
551 typedef mpl::false_ type;
554 template <class K>
555 struct optimized
557 typedef mpl::true_ type;
560 template <class K>
561 struct optimized<K**>
563 typedef mpl::false_ type;
566 template <class T>
567 struct make_kw_spec;
569 template <class K, class T>
570 struct make_kw_spec<K(T)>
572 typedef arg_spec<
573 typename keyword<K>::type
574 , typename required<K>::type
575 , typename optimized<K>::type
577 > type;
580 } // namespace aux
582 template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
583 struct init
584 : boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
586 init(CallPolicies call_policies = CallPolicies())
587 : call_policies(call_policies)
590 template <class CallPolicies1>
591 init<ParameterSpecs, CallPolicies1>
592 operator[](CallPolicies1 const& call_policies) const
594 return init<ParameterSpecs, CallPolicies1>(call_policies);
597 template <class Class>
598 void visit_aux(Class& cl, mpl::true_) const
600 cl.def(boost::python::init<>()[call_policies]);
603 template <class Class>
604 void visit_aux(Class& cl, mpl::false_) const
606 typedef typename mpl::transform<
607 ParameterSpecs
608 , aux::make_kw_spec<mpl::_>
609 , mpl::back_inserter<mpl::vector0<> >
610 >::type arg_specs;
612 typedef typename mpl::count_if<
613 arg_specs
614 , aux::is_optional<mpl::_>
615 >::type optional_arity;
617 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
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
628 template <class Class>
629 void visit(Class& cl) const
631 visit_aux(cl, mpl::empty<ParameterSpecs>());
634 CallPolicies call_policies;
637 template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
638 struct call
639 : boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
641 call(CallPolicies const& call_policies = CallPolicies())
642 : call_policies(call_policies)
645 template <class CallPolicies1>
646 call<ParameterSpecs, CallPolicies1>
647 operator[](CallPolicies1 const& call_policies) const
649 return call<ParameterSpecs, CallPolicies1>(call_policies);
652 template <class Class>
653 void visit(Class& cl) const
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;
662 typedef typename mpl::front<ParameterSpecs>::type result_type;
664 typedef typename mpl::transform<
665 arg_types
666 , aux::make_kw_spec<mpl::_>
667 , mpl::back_inserter<mpl::vector0<> >
668 >::type arg_specs;
670 typedef typename mpl::count_if<
671 arg_specs
672 , aux::is_optional<mpl::_>
673 >::type optional_arity;
675 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
677 typedef aux::call_policies_as_options<CallPolicies> options;
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
688 CallPolicies call_policies;
691 template <class Fwd, class ParameterSpecs>
692 struct function
693 : boost::python::def_visitor<function<Fwd, ParameterSpecs> >
695 template <class Class, class Options>
696 void visit(Class& cl, char const* name, Options const& options) const
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;
705 typedef typename mpl::front<ParameterSpecs>::type result_type;
707 typedef typename mpl::transform<
708 arg_types
709 , aux::make_kw_spec<mpl::_>
710 , mpl::back_inserter<mpl::vector0<> >
711 >::type arg_specs;
713 typedef typename mpl::count_if<
714 arg_specs
715 , aux::is_optional<mpl::_>
716 >::type optional_arity;
718 typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
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
732 }}} // namespace boost::parameter::python
734 #endif // BOOST_PARAMETER_PYTHON_060209_HPP