ossrv_pub/boost_apis/boost/parameter/python.hpp
changeset 0 e4d67989cc36
--- /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
+