ossrv_pub/boost_apis/boost/python/init.hpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/python/init.hpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,421 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright David Abrahams 2002, Joel de Guzman, 2002.
+// Distributed under 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 INIT_JDG20020820_HPP
+#define INIT_JDG20020820_HPP
+
+# include <boost/python/detail/prefix.hpp>
+
+#include <boost/python/detail/type_list.hpp>
+#include <boost/python/args_fwd.hpp>
+#include <boost/python/detail/make_keyword_range_fn.hpp>
+#include <boost/python/def_visitor.hpp>
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/iterator_range.hpp>
+#include <boost/mpl/empty.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/prior.hpp>
+#include <boost/mpl/joint_view.hpp>
+#include <boost/mpl/back.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/preprocessor/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/enum_params.hpp>
+
+#include <utility>
+
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT                                \
+    BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(                                        \
+        BOOST_PYTHON_MAX_ARITY,                                                 \
+        class T,                                                                \
+        mpl::void_)                                                             \
+
+#define BOOST_PYTHON_OVERLOAD_TYPES                                             \
+    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
+        BOOST_PYTHON_MAX_ARITY,                                                 \
+        class T)                                                                \
+
+#define BOOST_PYTHON_OVERLOAD_ARGS                                              \
+    BOOST_PP_ENUM_PARAMS_Z(1,                                                   \
+        BOOST_PYTHON_MAX_ARITY,                                                 \
+        T)                                                                      \
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace python {
+
+template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
+class init; // forward declaration
+
+
+template <BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT>
+struct optional; // forward declaration
+
+namespace detail
+{
+  namespace error
+  {
+    template <int keywords, int init_args>
+    struct more_keywords_than_init_arguments
+    {
+        typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1];
+    };
+  }
+
+  //  is_optional<T>::value
+  //
+  //      This metaprogram checks if T is an optional
+  //
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+    template <class T>
+    struct is_optional {
+
+    private:
+
+        template <BOOST_PYTHON_OVERLOAD_TYPES>
+        static boost::type_traits::yes_type f(optional<BOOST_PYTHON_OVERLOAD_ARGS>);
+        static boost::type_traits::no_type f(...);
+        static T t();
+
+    public:
+
+        BOOST_STATIC_CONSTANT(
+            bool, value =
+                sizeof(f(t())) == sizeof(::boost::type_traits::yes_type));
+        typedef mpl::bool_<value> type;
+    };
+
+#else
+
+    template <class T>
+    struct is_optional
+      : mpl::false_
+    {};
+
+    template <BOOST_PYTHON_OVERLOAD_TYPES>
+    struct is_optional<optional<BOOST_PYTHON_OVERLOAD_ARGS> >
+      : mpl::true_
+    {};
+  
+#endif
+
+  template <int NDefaults>
+  struct define_class_init_helper;
+
+} // namespace detail
+
+template <class DerivedT>
+struct init_base : def_visitor<DerivedT>
+{
+    init_base(char const* doc_, detail::keyword_range const& keywords_)
+        : m_doc(doc_), m_keywords(keywords_)
+    {}
+        
+    init_base(char const* doc_)
+        : m_doc(doc_)
+    {}
+
+    DerivedT const& derived() const
+    {
+        return *static_cast<DerivedT const*>(this);
+    }
+    
+    char const* doc_string() const
+    {
+        return m_doc;
+    }
+
+    detail::keyword_range const& keywords() const
+    {
+        return m_keywords;
+    }
+
+    static default_call_policies call_policies()
+    {
+        return default_call_policies();
+    }
+
+ private:
+    //  visit
+    //
+    //      Defines a set of n_defaults + 1 constructors for its
+    //      class_<...> argument. Each constructor after the first has
+    //      one less argument to its right. Example:
+    //
+    //          init<int, optional<char, long, double> >
+    //
+    //      Defines:
+    //
+    //          __init__(int, char, long, double)
+    //          __init__(int, char, long)
+    //          __init__(int, char)
+    //          __init__(int)
+    template <class classT>
+    void visit(classT& cl) const
+    {
+        typedef typename DerivedT::signature signature;
+        typedef typename DerivedT::n_arguments n_arguments;
+        typedef typename DerivedT::n_defaults n_defaults;
+    
+        detail::define_class_init_helper<n_defaults::value>::apply(
+            cl
+          , derived().call_policies()
+          , signature()
+          , n_arguments()
+          , derived().doc_string()
+          , derived().keywords());
+    }
+    
+    friend class python::def_visitor_access;
+    
+ private: // data members
+    char const* m_doc;
+    detail::keyword_range m_keywords;
+};
+
+template <class CallPoliciesT, class InitT>
+class init_with_call_policies
+    : public init_base<init_with_call_policies<CallPoliciesT, InitT> >
+{
+    typedef init_base<init_with_call_policies<CallPoliciesT, InitT> > base;
+ public:
+    typedef typename InitT::n_arguments n_arguments;
+    typedef typename InitT::n_defaults n_defaults;
+    typedef typename InitT::signature signature;
+
+    init_with_call_policies(
+        CallPoliciesT const& policies_
+        , char const* doc_
+        , detail::keyword_range const& keywords
+        )
+        : base(doc_, keywords)
+        , m_policies(policies_)
+    {}
+
+    CallPoliciesT const& call_policies() const
+    {
+        return this->m_policies;
+    }
+    
+ private: // data members
+    CallPoliciesT m_policies;
+};
+
+//
+// drop1<S> is the initial length(S) elements of S
+//
+namespace detail
+{
+  template <class S>
+  struct drop1
+    : mpl::iterator_range<
+          typename mpl::begin<S>::type
+        , typename mpl::prior<
+              typename mpl::end<S>::type
+          >::type
+      >
+  {};
+}
+
+template <BOOST_PYTHON_OVERLOAD_TYPES>
+class init : public init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> >
+{
+    typedef init_base<init<BOOST_PYTHON_OVERLOAD_ARGS> > base;
+ public:
+    typedef init<BOOST_PYTHON_OVERLOAD_ARGS> self_t;
+
+    init(char const* doc_ = 0)
+        : base(doc_)
+    {
+    }
+
+    template <std::size_t N>
+    init(char const* doc_, detail::keywords<N> const& kw)
+        : base(doc_, kw.range())
+    {
+        typedef typename detail::error::more_keywords_than_init_arguments<
+            N, n_arguments::value
+            >::too_many_keywords assertion;
+    }
+
+    template <std::size_t N>
+    init(detail::keywords<N> const& kw, char const* doc_ = 0)
+        : base(doc_, kw.range())
+    {
+        typedef typename detail::error::more_keywords_than_init_arguments<
+            N, n_arguments::value
+            >::too_many_keywords assertion;
+    }
+
+    template <class CallPoliciesT>
+    init_with_call_policies<CallPoliciesT, self_t>
+    operator[](CallPoliciesT const& policies) const
+    {
+        return init_with_call_policies<CallPoliciesT, self_t>(
+            policies, this->doc_string(), this->keywords());
+    }
+
+    typedef detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS> signature_;
+
+    typedef detail::is_optional<
+        typename mpl::eval_if<
+            mpl::empty<signature_>
+          , mpl::false_
+          , mpl::back<signature_>
+        >::type
+    > back_is_optional;
+    
+    typedef typename mpl::eval_if<
+        back_is_optional
+      , mpl::back<signature_>
+      , mpl::vector0<>
+    >::type optional_args;
+
+    typedef typename mpl::eval_if<
+        back_is_optional
+      , mpl::if_<
+            mpl::empty<optional_args>
+          , detail::drop1<signature_>
+          , mpl::joint_view<
+                detail::drop1<signature_>
+              , optional_args
+            >
+        >
+      , signature_
+    >::type signature;
+
+    // TODO: static assert to make sure there are no other optional elements
+
+    // Count the number of default args
+    typedef mpl::size<optional_args> n_defaults;
+    typedef mpl::size<signature> n_arguments;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  optional
+//
+//      optional<T0...TN>::type returns a typelist.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <BOOST_PYTHON_OVERLOAD_TYPES>
+struct optional
+    : detail::type_list<BOOST_PYTHON_OVERLOAD_ARGS>
+{
+};
+
+namespace detail
+{
+  template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
+  inline void def_init_aux(
+      ClassT& cl
+      , Signature const&
+      , NArgs
+      , CallPoliciesT const& policies
+      , char const* doc
+      , detail::keyword_range const& keywords_
+      )
+  {
+      cl.def(
+          "__init__"
+        , detail::make_keyword_range_constructor<Signature,NArgs>(
+              policies
+            , keywords_
+            , (typename ClassT::metadata::holder*)0
+          )
+        , doc
+      );
+  }
+
+  ///////////////////////////////////////////////////////////////////////////////
+  //
+  //  define_class_init_helper<N>::apply
+  //
+  //      General case
+  //
+  //      Accepts a class_ and an arguments list. Defines a constructor
+  //      for the class given the arguments and recursively calls
+  //      define_class_init_helper<N-1>::apply with one fewer argument (the
+  //      rightmost argument is shaved off)
+  //
+  ///////////////////////////////////////////////////////////////////////////////
+  template <int NDefaults>
+  struct define_class_init_helper
+  {
+
+      template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
+      static void apply(
+          ClassT& cl
+          , CallPoliciesT const& policies
+          , Signature const& args
+          , NArgs
+          , char const* doc
+          , detail::keyword_range keywords)
+      {
+          detail::def_init_aux(cl, args, NArgs(), policies, 0, keywords);
+
+          if (keywords.second > keywords.first)
+              --keywords.second;
+
+          typedef typename mpl::prior<NArgs>::type next_nargs;
+          define_class_init_helper<NDefaults-1>::apply(
+              cl, policies, Signature(), next_nargs(), doc, keywords);
+      }
+  };
+
+  ///////////////////////////////////////////////////////////////////////////////
+  //
+  //  define_class_init_helper<0>::apply
+  //
+  //      Terminal case
+  //
+  //      Accepts a class_ and an arguments list. Defines a constructor
+  //      for the class given the arguments.
+  //
+  ///////////////////////////////////////////////////////////////////////////////
+  template <>
+  struct define_class_init_helper<0> {
+
+      template <class ClassT, class CallPoliciesT, class Signature, class NArgs>
+      static void apply(
+          ClassT& cl
+        , CallPoliciesT const& policies
+        , Signature const& args
+        , NArgs
+        , char const* doc
+        , detail::keyword_range const& keywords)
+      {
+          detail::def_init_aux(cl, args, NArgs(), policies, doc, keywords);
+      }
+  };
+}
+
+}} // namespace boost::python
+
+#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT
+#undef BOOST_PYTHON_OVERLOAD_TYPES
+#undef BOOST_PYTHON_OVERLOAD_ARGS
+#undef BOOST_PYTHON_IS_OPTIONAL_VALUE
+#undef BOOST_PYTHON_APPEND_TO_INIT
+
+///////////////////////////////////////////////////////////////////////////////
+#endif // INIT_JDG20020820_HPP
+
+
+
+
+
+
+
+