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