736 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			736 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | // 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
 | ||
|  | 
 |