--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/parameter/python.hpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,735 @@
+// Copyright Daniel Wallin 2006. Use, modification and distribution is
+// subject to the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PARAMETER_PYTHON_060209_HPP
+# define BOOST_PARAMETER_PYTHON_060209_HPP
+
+# include <boost/mpl/vector.hpp>
+# include <boost/mpl/fold.hpp>
+# include <boost/mpl/prior.hpp>
+# include <boost/mpl/shift_right.hpp>
+# include <boost/mpl/shift_left.hpp>
+# include <boost/mpl/bitand.hpp>
+# include <boost/mpl/pair.hpp>
+# include <boost/mpl/size.hpp>
+# include <boost/mpl/push_back.hpp>
+# include <boost/mpl/or.hpp>
+# include <boost/mpl/count_if.hpp>
+# include <boost/mpl/transform.hpp>
+# include <boost/mpl/front.hpp>
+# include <boost/mpl/iterator_range.hpp>
+# include <boost/mpl/next.hpp>
+# include <boost/mpl/begin_end.hpp>
+# include <boost/mpl/not.hpp>
+# include <boost/mpl/empty.hpp>
+# include <boost/python/def.hpp>
+# include <boost/python/make_constructor.hpp>
+# include <boost/python/init.hpp>
+# include <boost/python/to_python_converter.hpp>
+# include <boost/parameter/aux_/maybe.hpp>
+# include <boost/parameter/aux_/python/invoker.hpp>
+
+namespace boost { namespace parameter { namespace python
+{
+ namespace python_ = boost::python;
+}}}
+
+namespace boost { namespace parameter { namespace python { namespace aux
+{
+
+ inline PyObject* unspecified_type()
+ {
+ static PyTypeObject unspecified = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "Boost.Parameter.Unspecified", /* tp_name */
+ PyType_Type.tp_basicsize, /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ };
+
+ if (unspecified.ob_type == 0)
+ {
+ unspecified.ob_type = &PyType_Type;
+ PyType_Ready(&unspecified);
+ }
+
+ return (PyObject*)&unspecified;
+ }
+
+ struct empty_tag {};
+
+ struct empty_tag_to_python
+ {
+ static PyObject* convert(empty_tag)
+ {
+ return python_::xincref(unspecified_type());
+ }
+ };
+
+}}}} // namespace boost::parameter::python::aux
+
+namespace boost { namespace python
+{
+
+ // Converts a Python value to a maybe<T>
+ template <class T>
+ struct arg_from_python<parameter::aux::maybe<T> >
+ : arg_from_python<T>
+ {
+ arg_from_python(PyObject* p)
+ : arg_from_python<T>(p)
+ , empty(parameter::python::aux::unspecified_type() == p)
+ {}
+
+ bool convertible() const
+ {
+ return empty || arg_from_python<T>::convertible();
+ }
+
+ parameter::aux::maybe<T> operator()()
+ {
+ if (empty)
+ {
+ return parameter::aux::maybe<T>();
+ }
+ else
+ {
+ return parameter::aux::maybe<T>(
+ arg_from_python<T>::operator()()
+ );
+ }
+ }
+
+ bool empty;
+ };
+
+}} // namespace boost::python
+
+namespace boost { namespace parameter { namespace python {
+
+namespace aux
+{
+
+ template <class K>
+ struct is_optional
+ : mpl::not_<
+ mpl::or_<typename K::required, typename K::optimized_default>
+ >
+ {};
+
+ template <class K, class Required, class Optimized, class T>
+ struct arg_spec
+ {
+ typedef K keyword;
+ typedef Required required;
+ typedef T type;
+ typedef Optimized optimized_default;
+ };
+
+ template <class K, class T, class Optimized = mpl::false_>
+ struct make_arg_spec_impl
+ {
+ typedef arg_spec<
+ typename K::first, typename K::second, Optimized, T
+ > type;
+ };
+
+ template <class K, class T>
+ struct make_arg_spec_impl<K, T, typename K::third>
+ {
+ typedef arg_spec<
+ typename K::first, typename K::second, typename K::third, T
+ > type;
+ };
+
+ template <class K, class T>
+ struct make_arg_spec
+ : make_arg_spec_impl<K, T>
+ {
+ };
+
+ template <class Spec, class State>
+ struct combinations_op
+ {
+ typedef typename State::second bits;
+ typedef typename State::first result0;
+
+ typedef typename mpl::if_<
+ mpl::or_<
+ typename Spec::required
+ , typename Spec::optimized_default
+ , mpl::bitand_<bits, mpl::long_<1> >
+ >
+ , typename mpl::push_back<result0, Spec>::type
+ , result0
+ >::type result;
+
+ typedef typename mpl::if_<
+ mpl::or_<
+ typename Spec::required
+ , typename Spec::optimized_default
+ >
+ , bits
+ , typename mpl::shift_right<bits, mpl::long_<1> >::type
+ >::type next_bits;
+
+ typedef mpl::pair<
+ result
+ , next_bits
+ > type;
+ };
+
+ // Used as start value in the recursive arg() composition below.
+ struct no_keywords
+ {
+ template <class T>
+ T const& operator,(T const& x) const
+ {
+ return x;
+ }
+ };
+
+ template <class Def, class F, class Iter, class End, class Keywords>
+ void def_combination_aux0(
+ Def def, F f, Iter, End, Keywords const& keywords, mpl::false_)
+ {
+ typedef typename mpl::deref<Iter>::type spec;
+ typedef typename spec::keyword kw;
+
+ def_combination_aux(
+ def, f, typename mpl::next<Iter>::type(), End()
+ , (
+ keywords, boost::python::arg(kw::keyword_name())
+ )
+ );
+ }
+
+ template <class Def, class F, class Iter, class End, class Keywords>
+ void def_combination_aux0(
+ Def def, F f, Iter, End, Keywords const& keywords, mpl::true_)
+ {
+ typedef typename mpl::deref<Iter>::type spec;
+ typedef typename spec::keyword kw;
+
+ def_combination_aux(
+ def, f, typename mpl::next<Iter>::type(), End()
+ , (
+ keywords, boost::python::arg(kw::keyword_name()) = empty_tag()
+ )
+ );
+ }
+
+ inline void initialize_converter()
+ {
+ static python_::to_python_converter<empty_tag, empty_tag_to_python> x;
+ }
+
+ template <class Def, class F, class Iter, class End, class Keywords>
+ void def_combination_aux(
+ Def def, F f, Iter, End, Keywords const& keywords)
+ {
+ typedef typename mpl::deref<Iter>::type spec;
+
+ typedef typename mpl::and_<
+ typename spec::optimized_default
+ , mpl::not_<typename spec::required>
+ >::type optimized_default;
+
+ def_combination_aux0(
+ def, f, Iter(), End(), keywords, optimized_default()
+ );
+ }
+
+ template <class Def, class F, class End, class Keywords>
+ void def_combination_aux(
+ Def def, F f, End, End, Keywords const& keywords)
+ {
+ def(f, keywords);
+ }
+
+ template <class Def, class F, class End>
+ void def_combination_aux(
+ Def def, F f, End, End, no_keywords const&)
+ {
+ def(f);
+ }
+
+ template <
+ class Def, class Specs, class Bits, class Invoker
+ >
+ void def_combination(
+ Def def, Specs*, Bits, Invoker*)
+ {
+ typedef typename mpl::fold<
+ Specs
+ , mpl::pair<mpl::vector0<>, Bits>
+ , combinations_op<mpl::_2, mpl::_1>
+ >::type combination0;
+
+ typedef typename combination0::first combination;
+
+ typedef typename mpl::apply_wrap1<
+ Invoker, combination
+ >::type invoker;
+
+ def_combination_aux(
+ def
+ , &invoker::execute
+ , typename mpl::begin<combination>::type()
+ , typename mpl::end<combination>::type()
+ , no_keywords()
+ );
+ }
+
+ template <
+ class Def, class Specs, class Bits, class End, class Invoker
+ >
+ void def_combinations(
+ Def def, Specs*, Bits, End, Invoker*)
+ {
+ initialize_converter();
+
+ def_combination(def, (Specs*)0, Bits(), (Invoker*)0);
+
+ def_combinations(
+ def
+ , (Specs*)0
+ , mpl::long_<Bits::value + 1>()
+ , End()
+ , (Invoker*)0
+ );
+ }
+
+ template <
+ class Def, class Specs, class End, class Invoker
+ >
+ void def_combinations(
+ Def, Specs*, End, End, Invoker*)
+ {}
+
+ struct not_specified {};
+
+ template <class CallPolicies>
+ struct call_policies_as_options
+ {
+ call_policies_as_options(CallPolicies const& call_policies)
+ : call_policies(call_policies)
+ {}
+
+ CallPolicies const& policies() const
+ {
+ return call_policies;
+ }
+
+ char const* doc() const
+ {
+ return 0;
+ }
+
+ CallPolicies call_policies;
+ };
+
+ template <class Class, class Options = not_specified>
+ struct def_class
+ {
+ def_class(Class& cl, char const* name, Options options = Options())
+ : cl(cl)
+ , name(name)
+ , options(options)
+ {}
+
+ template <class F>
+ void def(F f, not_specified const*) const
+ {
+ cl.def(name, f);
+ }
+
+ template <class F>
+ void def(F f, void const*) const
+ {
+ cl.def(name, f, options.doc(), options.policies());
+ }
+
+ template <class F>
+ void operator()(F f) const
+ {
+ this->def(f, &options);
+ }
+
+ template <class F, class Keywords>
+ void def(F f, Keywords const& keywords, not_specified const*) const
+ {
+ cl.def(name, f, keywords);
+ }
+
+ template <class F, class Keywords>
+ void def(F f, Keywords const& keywords, void const*) const
+ {
+ cl.def(name, f, keywords, options.doc(), options.policies());
+ }
+
+ template <class F, class Keywords>
+ void operator()(F f, Keywords const& keywords) const
+ {
+ this->def(f, keywords, &options);
+ }
+
+ Class& cl;
+ char const* name;
+ Options options;
+ };
+
+ template <class Class, class CallPolicies = boost::python::default_call_policies>
+ struct def_init
+ {
+ def_init(Class& cl, CallPolicies call_policies = CallPolicies())
+ : cl(cl)
+ , call_policies(call_policies)
+ {}
+
+ template <class F>
+ void operator()(F f) const
+ {
+ cl.def(
+ "__init__"
+ , boost::python::make_constructor(f, call_policies)
+ );
+ }
+
+ template <class F, class Keywords>
+ void operator()(F f, Keywords const& keywords) const
+ {
+ cl.def(
+ "__init__"
+ , boost::python::make_constructor(f, call_policies, keywords)
+ );
+ }
+
+ Class& cl;
+ CallPolicies call_policies;
+ };
+
+ struct def_function
+ {
+ def_function(char const* name)
+ : name(name)
+ {}
+
+ template <class F>
+ void operator()(F f) const
+ {
+ boost::python::def(name, f);
+ }
+
+ template <class F, class Keywords>
+ void operator()(F f, Keywords const& keywords) const
+ {
+ boost::python::def(name, f, keywords);
+ }
+
+ char const* name;
+ };
+
+} // namespace aux
+
+template <class M, class Signature>
+void def(char const* name, Signature)
+{
+ typedef mpl::iterator_range<
+ typename mpl::next<
+ typename mpl::begin<Signature>::type
+ >::type
+ , typename mpl::end<Signature>::type
+ > arg_types;
+
+ typedef typename mpl::transform<
+ typename M::keywords
+ , arg_types
+ , aux::make_arg_spec<mpl::_1, mpl::_2>
+ , mpl::back_inserter<mpl::vector0<> >
+ >::type arg_specs;
+
+ typedef typename mpl::count_if<
+ arg_specs
+ , aux::is_optional<mpl::_1>
+ >::type optional_arity;
+
+ typedef typename mpl::front<Signature>::type result_type;
+ typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
+
+ aux::def_combinations(
+ aux::def_function(name)
+ , (arg_specs*)0
+ , mpl::long_<0>()
+ , mpl::long_<upper::value>()
+ , (aux::make_invoker<M, result_type>*)0
+ );
+}
+
+template <class M, class Class, class Signature>
+void def(Class& cl, char const* name, Signature)
+{
+ typedef mpl::iterator_range<
+ typename mpl::next<
+ typename mpl::begin<Signature>::type
+ >::type
+ , typename mpl::end<Signature>::type
+ > arg_types;
+
+ typedef typename mpl::transform<
+ typename M::keywords
+ , arg_types
+ , aux::make_arg_spec<mpl::_1, mpl::_2>
+ , mpl::back_inserter<mpl::vector0<> >
+ >::type arg_specs;
+
+ typedef typename mpl::count_if<
+ arg_specs
+ , aux::is_optional<mpl::_1>
+ >::type optional_arity;
+
+ typedef typename mpl::front<Signature>::type result_type;
+ typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
+
+ aux::def_combinations(
+ aux::def_class<Class>(cl, name)
+ , (arg_specs*)0
+ , mpl::long_<0>()
+ , mpl::long_<upper::value>()
+ , (aux::make_invoker<M, result_type>*)0
+ );
+}
+
+namespace aux
+{
+
+ template <class K>
+ struct keyword
+ {
+ typedef K type;
+ };
+
+ template <class K>
+ struct keyword<K*>
+ {
+ typedef K type;
+ };
+
+ template <class K>
+ struct keyword<K**>
+ {
+ typedef K type;
+ };
+
+ template <class K>
+ struct required
+ {
+ typedef mpl::true_ type;
+ };
+
+ template <class K>
+ struct required<K*>
+ {
+ typedef mpl::false_ type;
+ };
+
+ template <class K>
+ struct optimized
+ {
+ typedef mpl::true_ type;
+ };
+
+ template <class K>
+ struct optimized<K**>
+ {
+ typedef mpl::false_ type;
+ };
+
+ template <class T>
+ struct make_kw_spec;
+
+ template <class K, class T>
+ struct make_kw_spec<K(T)>
+ {
+ typedef arg_spec<
+ typename keyword<K>::type
+ , typename required<K>::type
+ , typename optimized<K>::type
+ , T
+ > type;
+ };
+
+} // namespace aux
+
+template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
+struct init
+ : boost::python::def_visitor<init<ParameterSpecs, CallPolicies> >
+{
+ init(CallPolicies call_policies = CallPolicies())
+ : call_policies(call_policies)
+ {}
+
+ template <class CallPolicies1>
+ init<ParameterSpecs, CallPolicies1>
+ operator[](CallPolicies1 const& call_policies) const
+ {
+ return init<ParameterSpecs, CallPolicies1>(call_policies);
+ }
+
+ template <class Class>
+ void visit_aux(Class& cl, mpl::true_) const
+ {
+ cl.def(boost::python::init<>()[call_policies]);
+ }
+
+ template <class Class>
+ void visit_aux(Class& cl, mpl::false_) const
+ {
+ typedef typename mpl::transform<
+ ParameterSpecs
+ , aux::make_kw_spec<mpl::_>
+ , mpl::back_inserter<mpl::vector0<> >
+ >::type arg_specs;
+
+ typedef typename mpl::count_if<
+ arg_specs
+ , aux::is_optional<mpl::_>
+ >::type optional_arity;
+
+ typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
+
+ aux::def_combinations(
+ aux::def_init<Class, CallPolicies>(cl, call_policies)
+ , (arg_specs*)0
+ , mpl::long_<0>()
+ , mpl::long_<upper::value>()
+ , (aux::make_init_invoker<typename Class::wrapped_type>*)0
+ );
+ }
+
+ template <class Class>
+ void visit(Class& cl) const
+ {
+ visit_aux(cl, mpl::empty<ParameterSpecs>());
+ }
+
+ CallPolicies call_policies;
+};
+
+template <class ParameterSpecs, class CallPolicies = boost::python::default_call_policies>
+struct call
+ : boost::python::def_visitor<call<ParameterSpecs, CallPolicies> >
+{
+ call(CallPolicies const& call_policies = CallPolicies())
+ : call_policies(call_policies)
+ {}
+
+ template <class CallPolicies1>
+ call<ParameterSpecs, CallPolicies1>
+ operator[](CallPolicies1 const& call_policies) const
+ {
+ return call<ParameterSpecs, CallPolicies1>(call_policies);
+ }
+
+ template <class Class>
+ void visit(Class& cl) const
+ {
+ typedef mpl::iterator_range<
+ typename mpl::next<
+ typename mpl::begin<ParameterSpecs>::type
+ >::type
+ , typename mpl::end<ParameterSpecs>::type
+ > arg_types;
+
+ typedef typename mpl::front<ParameterSpecs>::type result_type;
+
+ typedef typename mpl::transform<
+ arg_types
+ , aux::make_kw_spec<mpl::_>
+ , mpl::back_inserter<mpl::vector0<> >
+ >::type arg_specs;
+
+ typedef typename mpl::count_if<
+ arg_specs
+ , aux::is_optional<mpl::_>
+ >::type optional_arity;
+
+ typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
+
+ typedef aux::call_policies_as_options<CallPolicies> options;
+
+ aux::def_combinations(
+ aux::def_class<Class, options>(cl, "__call__", options(call_policies))
+ , (arg_specs*)0
+ , mpl::long_<0>()
+ , mpl::long_<upper::value>()
+ , (aux::make_call_invoker<typename Class::wrapped_type, result_type>*)0
+ );
+ }
+
+ CallPolicies call_policies;
+};
+
+template <class Fwd, class ParameterSpecs>
+struct function
+ : boost::python::def_visitor<function<Fwd, ParameterSpecs> >
+{
+ template <class Class, class Options>
+ void visit(Class& cl, char const* name, Options const& options) const
+ {
+ typedef mpl::iterator_range<
+ typename mpl::next<
+ typename mpl::begin<ParameterSpecs>::type
+ >::type
+ , typename mpl::end<ParameterSpecs>::type
+ > arg_types;
+
+ typedef typename mpl::front<ParameterSpecs>::type result_type;
+
+ typedef typename mpl::transform<
+ arg_types
+ , aux::make_kw_spec<mpl::_>
+ , mpl::back_inserter<mpl::vector0<> >
+ >::type arg_specs;
+
+ typedef typename mpl::count_if<
+ arg_specs
+ , aux::is_optional<mpl::_>
+ >::type optional_arity;
+
+ typedef typename mpl::shift_left<mpl::long_<1>, optional_arity>::type upper;
+
+ aux::def_combinations(
+ aux::def_class<Class, Options>(cl, name, options)
+ , (arg_specs*)0
+ , mpl::long_<0>()
+ , mpl::long_<upper::value>()
+ , (aux::make_member_invoker<
+ Fwd, result_type, typename Class::wrapped_type
+ >*)0
+ );
+ }
+};
+
+}}} // namespace boost::parameter::python
+
+#endif // BOOST_PARAMETER_PYTHON_060209_HPP
+