diff -r 000000000000 -r e4d67989cc36 ossrv_pub/boost_apis/boost/parameter/python.hpp --- /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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +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 + template + struct arg_from_python > + : arg_from_python + { + arg_from_python(PyObject* p) + : arg_from_python(p) + , empty(parameter::python::aux::unspecified_type() == p) + {} + + bool convertible() const + { + return empty || arg_from_python::convertible(); + } + + parameter::aux::maybe operator()() + { + if (empty) + { + return parameter::aux::maybe(); + } + else + { + return parameter::aux::maybe( + arg_from_python::operator()() + ); + } + } + + bool empty; + }; + +}} // namespace boost::python + +namespace boost { namespace parameter { namespace python { + +namespace aux +{ + + template + struct is_optional + : mpl::not_< + mpl::or_ + > + {}; + + template + struct arg_spec + { + typedef K keyword; + typedef Required required; + typedef T type; + typedef Optimized optimized_default; + }; + + template + struct make_arg_spec_impl + { + typedef arg_spec< + typename K::first, typename K::second, Optimized, T + > type; + }; + + template + struct make_arg_spec_impl + { + typedef arg_spec< + typename K::first, typename K::second, typename K::third, T + > type; + }; + + template + struct make_arg_spec + : make_arg_spec_impl + { + }; + + template + 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_ > + > + , typename mpl::push_back::type + , result0 + >::type result; + + typedef typename mpl::if_< + mpl::or_< + typename Spec::required + , typename Spec::optimized_default + > + , bits + , typename mpl::shift_right >::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 + T const& operator,(T const& x) const + { + return x; + } + }; + + template + void def_combination_aux0( + Def def, F f, Iter, End, Keywords const& keywords, mpl::false_) + { + typedef typename mpl::deref::type spec; + typedef typename spec::keyword kw; + + def_combination_aux( + def, f, typename mpl::next::type(), End() + , ( + keywords, boost::python::arg(kw::keyword_name()) + ) + ); + } + + template + void def_combination_aux0( + Def def, F f, Iter, End, Keywords const& keywords, mpl::true_) + { + typedef typename mpl::deref::type spec; + typedef typename spec::keyword kw; + + def_combination_aux( + def, f, typename mpl::next::type(), End() + , ( + keywords, boost::python::arg(kw::keyword_name()) = empty_tag() + ) + ); + } + + inline void initialize_converter() + { + static python_::to_python_converter x; + } + + template + void def_combination_aux( + Def def, F f, Iter, End, Keywords const& keywords) + { + typedef typename mpl::deref::type spec; + + typedef typename mpl::and_< + typename spec::optimized_default + , mpl::not_ + >::type optimized_default; + + def_combination_aux0( + def, f, Iter(), End(), keywords, optimized_default() + ); + } + + template + void def_combination_aux( + Def def, F f, End, End, Keywords const& keywords) + { + def(f, keywords); + } + + template + 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, Bits> + , combinations_op + >::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::type() + , typename mpl::end::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_() + , End() + , (Invoker*)0 + ); + } + + template < + class Def, class Specs, class End, class Invoker + > + void def_combinations( + Def, Specs*, End, End, Invoker*) + {} + + struct not_specified {}; + + template + 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 + struct def_class + { + def_class(Class& cl, char const* name, Options options = Options()) + : cl(cl) + , name(name) + , options(options) + {} + + template + void def(F f, not_specified const*) const + { + cl.def(name, f); + } + + template + void def(F f, void const*) const + { + cl.def(name, f, options.doc(), options.policies()); + } + + template + void operator()(F f) const + { + this->def(f, &options); + } + + template + void def(F f, Keywords const& keywords, not_specified const*) const + { + cl.def(name, f, keywords); + } + + template + void def(F f, Keywords const& keywords, void const*) const + { + cl.def(name, f, keywords, options.doc(), options.policies()); + } + + template + void operator()(F f, Keywords const& keywords) const + { + this->def(f, keywords, &options); + } + + Class& cl; + char const* name; + Options options; + }; + + template + struct def_init + { + def_init(Class& cl, CallPolicies call_policies = CallPolicies()) + : cl(cl) + , call_policies(call_policies) + {} + + template + void operator()(F f) const + { + cl.def( + "__init__" + , boost::python::make_constructor(f, call_policies) + ); + } + + template + 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 + void operator()(F f) const + { + boost::python::def(name, f); + } + + template + void operator()(F f, Keywords const& keywords) const + { + boost::python::def(name, f, keywords); + } + + char const* name; + }; + +} // namespace aux + +template +void def(char const* name, Signature) +{ + typedef mpl::iterator_range< + typename mpl::next< + typename mpl::begin::type + >::type + , typename mpl::end::type + > arg_types; + + typedef typename mpl::transform< + typename M::keywords + , arg_types + , aux::make_arg_spec + , mpl::back_inserter > + >::type arg_specs; + + typedef typename mpl::count_if< + arg_specs + , aux::is_optional + >::type optional_arity; + + typedef typename mpl::front::type result_type; + typedef typename mpl::shift_left, optional_arity>::type upper; + + aux::def_combinations( + aux::def_function(name) + , (arg_specs*)0 + , mpl::long_<0>() + , mpl::long_() + , (aux::make_invoker*)0 + ); +} + +template +void def(Class& cl, char const* name, Signature) +{ + typedef mpl::iterator_range< + typename mpl::next< + typename mpl::begin::type + >::type + , typename mpl::end::type + > arg_types; + + typedef typename mpl::transform< + typename M::keywords + , arg_types + , aux::make_arg_spec + , mpl::back_inserter > + >::type arg_specs; + + typedef typename mpl::count_if< + arg_specs + , aux::is_optional + >::type optional_arity; + + typedef typename mpl::front::type result_type; + typedef typename mpl::shift_left, optional_arity>::type upper; + + aux::def_combinations( + aux::def_class(cl, name) + , (arg_specs*)0 + , mpl::long_<0>() + , mpl::long_() + , (aux::make_invoker*)0 + ); +} + +namespace aux +{ + + template + struct keyword + { + typedef K type; + }; + + template + struct keyword + { + typedef K type; + }; + + template + struct keyword + { + typedef K type; + }; + + template + struct required + { + typedef mpl::true_ type; + }; + + template + struct required + { + typedef mpl::false_ type; + }; + + template + struct optimized + { + typedef mpl::true_ type; + }; + + template + struct optimized + { + typedef mpl::false_ type; + }; + + template + struct make_kw_spec; + + template + struct make_kw_spec + { + typedef arg_spec< + typename keyword::type + , typename required::type + , typename optimized::type + , T + > type; + }; + +} // namespace aux + +template +struct init + : boost::python::def_visitor > +{ + init(CallPolicies call_policies = CallPolicies()) + : call_policies(call_policies) + {} + + template + init + operator[](CallPolicies1 const& call_policies) const + { + return init(call_policies); + } + + template + void visit_aux(Class& cl, mpl::true_) const + { + cl.def(boost::python::init<>()[call_policies]); + } + + template + void visit_aux(Class& cl, mpl::false_) const + { + typedef typename mpl::transform< + ParameterSpecs + , aux::make_kw_spec + , mpl::back_inserter > + >::type arg_specs; + + typedef typename mpl::count_if< + arg_specs + , aux::is_optional + >::type optional_arity; + + typedef typename mpl::shift_left, optional_arity>::type upper; + + aux::def_combinations( + aux::def_init(cl, call_policies) + , (arg_specs*)0 + , mpl::long_<0>() + , mpl::long_() + , (aux::make_init_invoker*)0 + ); + } + + template + void visit(Class& cl) const + { + visit_aux(cl, mpl::empty()); + } + + CallPolicies call_policies; +}; + +template +struct call + : boost::python::def_visitor > +{ + call(CallPolicies const& call_policies = CallPolicies()) + : call_policies(call_policies) + {} + + template + call + operator[](CallPolicies1 const& call_policies) const + { + return call(call_policies); + } + + template + void visit(Class& cl) const + { + typedef mpl::iterator_range< + typename mpl::next< + typename mpl::begin::type + >::type + , typename mpl::end::type + > arg_types; + + typedef typename mpl::front::type result_type; + + typedef typename mpl::transform< + arg_types + , aux::make_kw_spec + , mpl::back_inserter > + >::type arg_specs; + + typedef typename mpl::count_if< + arg_specs + , aux::is_optional + >::type optional_arity; + + typedef typename mpl::shift_left, optional_arity>::type upper; + + typedef aux::call_policies_as_options options; + + aux::def_combinations( + aux::def_class(cl, "__call__", options(call_policies)) + , (arg_specs*)0 + , mpl::long_<0>() + , mpl::long_() + , (aux::make_call_invoker*)0 + ); + } + + CallPolicies call_policies; +}; + +template +struct function + : boost::python::def_visitor > +{ + template + void visit(Class& cl, char const* name, Options const& options) const + { + typedef mpl::iterator_range< + typename mpl::next< + typename mpl::begin::type + >::type + , typename mpl::end::type + > arg_types; + + typedef typename mpl::front::type result_type; + + typedef typename mpl::transform< + arg_types + , aux::make_kw_spec + , mpl::back_inserter > + >::type arg_specs; + + typedef typename mpl::count_if< + arg_specs + , aux::is_optional + >::type optional_arity; + + typedef typename mpl::shift_left, optional_arity>::type upper; + + aux::def_combinations( + aux::def_class(cl, name, options) + , (arg_specs*)0 + , mpl::long_<0>() + , mpl::long_() + , (aux::make_member_invoker< + Fwd, result_type, typename Class::wrapped_type + >*)0 + ); + } +}; + +}}} // namespace boost::parameter::python + +#endif // BOOST_PARAMETER_PYTHON_060209_HPP +