ossrv_pub/boost_apis/boost/python/class.hpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/python/class.hpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,654 @@
+// Copyright David Abrahams 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 CLASS_DWA200216_HPP
+# define CLASS_DWA200216_HPP
+
+# include <boost/python/detail/prefix.hpp>
+
+# include <boost/noncopyable.hpp>
+
+# include <boost/python/class_fwd.hpp>
+# include <boost/python/object/class.hpp>
+
+# include <boost/python/object.hpp>
+# include <boost/python/type_id.hpp>
+# include <boost/python/data_members.hpp>
+# include <boost/python/make_function.hpp>
+# include <boost/python/signature.hpp>
+# include <boost/python/init.hpp>
+# include <boost/python/args_fwd.hpp>
+
+# include <boost/python/object/class_metadata.hpp>
+# include <boost/python/object/pickle_support.hpp>
+# include <boost/python/object/add_to_namespace.hpp>
+
+# include <boost/python/detail/overloads_fwd.hpp>
+# include <boost/python/detail/operator_id.hpp>
+# include <boost/python/detail/def_helper.hpp>
+# include <boost/python/detail/force_instantiate.hpp>
+# include <boost/python/detail/unwrap_type_id.hpp>
+# include <boost/python/detail/unwrap_wrapper.hpp>
+
+# include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/is_member_function_pointer.hpp>
+# include <boost/type_traits/is_polymorphic.hpp>
+
+# include <boost/mpl/size.hpp>
+# include <boost/mpl/for_each.hpp>
+# include <boost/mpl/bool.hpp>
+# include <boost/mpl/not.hpp>
+
+# include <boost/detail/workaround.hpp>
+
+# if BOOST_WORKAROUND(__MWERKS__, <= 0x3004)                        \
+    /* pro9 reintroduced the bug */                                 \
+    || (BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
+        && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))   \
+    || BOOST_WORKAROUND(__GNUC__, < 3)
+
+#  define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
+
+# endif
+
+# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
+#  include <boost/mpl/and.hpp>
+#  include <boost/type_traits/is_member_pointer.hpp>
+# endif
+
+namespace boost { namespace python {
+
+template <class DerivedVisitor> class def_visitor;
+
+enum no_init_t { no_init };
+
+namespace detail
+{
+  // This function object is used with mpl::for_each to write the id
+  // of the type a pointer to which is passed as its 2nd compile-time
+  // argument. into the iterator pointed to by its runtime argument
+  struct write_type_id
+  {
+      write_type_id(type_info**p) : p(p) {}
+
+      // Here's the runtime behavior
+      template <class T>
+      void operator()(T*) const
+      {
+          *(*p)++ = type_id<T>();
+      }
+
+      type_info** p;
+  };
+
+  template <class T>
+  struct is_data_member_pointer
+      : mpl::and_<
+            is_member_pointer<T>
+          , mpl::not_<is_member_function_pointer<T> >
+        >
+  {};
+  
+# ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
+#  define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , detail::is_data_member_pointer<D>()
+#  define BOOST_PYTHON_YES_DATA_MEMBER , mpl::true_
+#  define BOOST_PYTHON_NO_DATA_MEMBER , mpl::false_
+# elif defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+#  define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , 0
+#  define BOOST_PYTHON_YES_DATA_MEMBER , int
+#  define BOOST_PYTHON_NO_DATA_MEMBER , ...
+# else 
+#  define BOOST_PYTHON_DATA_MEMBER_HELPER(D)
+#  define BOOST_PYTHON_YES_DATA_MEMBER
+#  define BOOST_PYTHON_NO_DATA_MEMBER
+# endif
+  
+  namespace error
+  {
+    //
+    // A meta-assertion mechanism which prints nice error messages and
+    // backtraces on lots of compilers. Usage:
+    //
+    //      assertion<C>::failed
+    //
+    // where C is an MPL metafunction class
+    //
+    
+    template <class C> struct assertion_failed { };
+    template <class C> struct assertion_ok { typedef C failed; };
+
+    template <class C>
+    struct assertion
+        : mpl::if_<C, assertion_ok<C>, assertion_failed<C> >::type
+    {};
+
+    //
+    // Checks for validity of arguments used to define virtual
+    // functions with default implementations.
+    //
+    
+    template <class Default>
+    void not_a_derived_class_member(Default) {}
+    
+    template <class T, class Fn>
+    struct virtual_function_default
+    {
+        template <class Default>
+        static void
+        must_be_derived_class_member(Default const&)
+        {
+            typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
+# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
+            typedef typename assertion<is_polymorphic<T> >::failed test1;
+# endif 
+            typedef typename assertion<is_member_function_pointer<Fn> >::failed test2;
+            not_a_derived_class_member<Default>(Fn());
+        }
+    };
+  }
+}
+
+// This is the primary mechanism through which users will expose
+// C++ classes to Python.
+template <
+    class W // class being wrapped
+    , class X1 // = detail::not_specified
+    , class X2 // = detail::not_specified
+    , class X3 // = detail::not_specified
+    >
+class class_ : public objects::class_base
+{
+ public: // types
+    typedef objects::class_base base;
+    typedef class_<W,X1,X2,X3> self;
+    typedef typename objects::class_metadata<W,X1,X2,X3> metadata;
+    typedef W wrapped_type;
+    
+ private: // types
+
+    // A helper class which will contain an array of id objects to be
+    // passed to the base class constructor
+    struct id_vector
+    {
+        typedef typename metadata::bases bases;
+        
+        id_vector()
+        {
+            // Stick the derived class id into the first element of the array
+            ids[0] = detail::unwrap_type_id((W*)0, (W*)0);
+
+            // Write the rest of the elements into succeeding positions.
+            type_info* p = ids + 1;
+            mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer<mpl::_>*)0);
+        }
+
+        BOOST_STATIC_CONSTANT(
+            std::size_t, size = mpl::size<bases>::value + 1);
+        type_info ids[size];
+    };
+    friend struct id_vector;
+
+ public: // constructors
+    
+    // Construct with the class name, with or without docstring, and default __init__() function
+    class_(char const* name, char const* doc = 0);
+
+    // Construct with class name, no docstring, and an uncallable __init__ function
+    class_(char const* name, no_init_t);
+
+    // Construct with class name, docstring, and an uncallable __init__ function
+    class_(char const* name, char const* doc, no_init_t);
+
+    // Construct with class name and init<> function
+    template <class DerivedT>
+    inline class_(char const* name, init_base<DerivedT> const& i)
+        : base(name, id_vector::size, id_vector().ids)
+    {
+        this->initialize(i);
+    }
+
+    // Construct with class name, docstring and init<> function
+    template <class DerivedT>
+    inline class_(char const* name, char const* doc, init_base<DerivedT> const& i)
+        : base(name, id_vector::size, id_vector().ids, doc)
+    {
+        this->initialize(i);
+    }
+
+ public: // member functions
+    
+    // Generic visitation
+    template <class Derived>
+    self& def(def_visitor<Derived> const& visitor)
+    {
+        visitor.visit(*this);
+        return *this;
+    }
+
+    // Wrap a member function or a non-member function which can take
+    // a T, T cv&, or T cv* as its first parameter, a callable
+    // python object, or a generic visitor.
+    template <class F>
+    self& def(char const* name, F f)
+    {
+        this->def_impl(
+            detail::unwrap_wrapper((W*)0)
+          , name, f, detail::def_helper<char const*>(0), &f);
+        return *this;
+    }
+
+    template <class A1, class A2>
+    self& def(char const* name, A1 a1, A2 const& a2)
+    {
+        this->def_maybe_overloads(name, a1, a2, &a2);
+        return *this;
+    }
+
+    template <class Fn, class A1, class A2>
+    self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2)
+    {
+        //  The arguments are definitely:
+        //      def(name, function, policy, doc_string)
+        //      def(name, function, doc_string, policy)
+
+        this->def_impl(
+            detail::unwrap_wrapper((W*)0)
+          , name, fn
+          , detail::def_helper<A1,A2>(a1,a2)
+          , &fn);
+
+        return *this;
+    }
+
+    template <class Fn, class A1, class A2, class A3>
+    self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
+    {
+        this->def_impl(
+            detail::unwrap_wrapper((W*)0)
+          , name, fn
+          , detail::def_helper<A1,A2,A3>(a1,a2,a3)
+          , &fn);
+
+        return *this;
+    }
+
+    //
+    // Data member access
+    //
+    template <class D>
+    self& def_readonly(char const* name, D const& d, char const* doc=0)
+    {
+        return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
+    }
+
+    template <class D>
+    self& def_readwrite(char const* name, D const& d, char const* doc=0)
+    {
+        return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
+    }
+    
+    template <class D>
+    self& def_readonly(char const* name, D& d, char const* doc=0)
+    {
+        return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
+    }
+
+    template <class D>
+    self& def_readwrite(char const* name, D& d, char const* doc=0)
+    {
+        return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
+    }
+
+    // Property creation
+# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+    template <class Get>
+    self& add_property(char const* name, Get fget, char const* docstr = 0)
+    {
+        base::add_property(name, this->make_getter(fget), docstr);
+        return *this;
+    }
+
+    template <class Get, class Set>
+    self& add_property(char const* name, Get fget, Set fset, char const* docstr = 0)
+    {
+        base::add_property(
+            name, this->make_getter(fget), this->make_setter(fset), docstr);
+        return *this;
+    }
+# else
+ private:
+    template <class Get>
+    self& add_property_impl(char const* name, Get fget, char const* docstr, int)
+    {
+        base::add_property(name, this->make_getter(fget), docstr);
+        return *this;
+    }
+
+    template <class Get, class Set>
+    self& add_property_impl(char const* name, Get fget, Set fset, ...)
+    {
+        base::add_property(
+            name, this->make_getter(fget), this->make_setter(fset), 0);
+        return *this;
+    }
+
+ public:    
+    template <class Get>
+    self& add_property(char const* name, Get fget)
+    {
+        base::add_property(name, this->make_getter(fget), 0);
+        return *this;
+    }
+
+    template <class Get, class DocStrOrSet>
+    self& add_property(char const* name, Get fget, DocStrOrSet docstr_or_set)
+    {
+        this->add_property_impl(name, this->make_getter(fget), docstr_or_set, 0);
+        return *this;
+    }
+
+    template <class Get, class Set>
+    self&
+    add_property(char const* name, Get fget, Set fset, char const* docstr)
+    {
+        base::add_property(
+            name, this->make_getter(fget), this->make_setter(fset), docstr);
+        return *this;
+    }
+# endif
+        
+    template <class Get>
+    self& add_static_property(char const* name, Get fget)
+    {
+        base::add_static_property(name, object(fget));
+        return *this;
+    }
+
+    template <class Get, class Set>
+    self& add_static_property(char const* name, Get fget, Set fset)
+    {
+        base::add_static_property(name, object(fget), object(fset));
+        return *this;
+    }
+        
+    template <class U>
+    self& setattr(char const* name, U const& x)
+    {
+        this->base::setattr(name, object(x));
+        return *this;
+    }
+
+    // Pickle support
+    template <typename PickleSuiteType>
+    self& def_pickle(PickleSuiteType const& x)
+    {
+      error_messages::must_be_derived_from_pickle_suite(x);
+      detail::pickle_suite_finalize<PickleSuiteType>::register_(
+        *this,
+        &PickleSuiteType::getinitargs,
+        &PickleSuiteType::getstate,
+        &PickleSuiteType::setstate,
+        PickleSuiteType::getstate_manages_dict());
+      return *this;
+    }
+
+    self& enable_pickling()
+    {
+        this->base::enable_pickling_(false);
+        return *this;
+    }
+
+    self& staticmethod(char const* name)
+    {
+        this->make_method_static(name);
+        return *this;
+    }
+ private: // helper functions
+
+    // Builds a method for this class around the given [member]
+    // function pointer or object, appropriately adjusting the type of
+    // the first signature argument so that if f is a member of a
+    // (possibly not wrapped) base class of T, an lvalue argument of
+    // type T will be required.
+    //
+    // @group PropertyHelpers {
+    template <class F>
+    object make_getter(F f)
+    {
+        typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
+        
+        return this->make_fn_impl(
+            detail::unwrap_wrapper((W*)0)
+          , f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
+        );
+    }
+    
+    template <class F>
+    object make_setter(F f)
+    {
+        typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
+        
+        return this->make_fn_impl(
+            detail::unwrap_wrapper((W*)0)
+          , f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
+        );
+    }
+    
+    template <class T, class F>
+    object make_fn_impl(T*, F const& f, mpl::false_, void*, mpl::false_)
+    {
+        return python::make_function(f, default_call_policies(), detail::get_signature(f, (T*)0));
+    }
+
+    template <class T, class D, class B>
+    object make_fn_impl(T*, D B::*pm_, mpl::false_, char*, mpl::true_)
+    {
+        D T::*pm = pm_;
+        return python::make_getter(pm);
+    }
+
+    template <class T, class D, class B>
+    object make_fn_impl(T*, D B::*pm_, mpl::false_, int*, mpl::true_)
+    {
+        D T::*pm = pm_;
+        return python::make_setter(pm);
+    }
+
+    template <class T, class F>
+    object make_fn_impl(T*, F const& x, mpl::true_, void*, mpl::false_)
+    {
+        return x;
+    }
+    // }
+    
+    template <class D, class B>
+    self& def_readonly_impl(
+        char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
+    {
+        return this->add_property(name, pm_, doc);
+    }
+
+    template <class D, class B>
+    self& def_readwrite_impl(
+        char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
+    {
+        return this->add_property(name, pm_, pm_, doc);
+    }
+
+    template <class D>
+    self& def_readonly_impl(
+        char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
+    {
+        return this->add_static_property(name, python::make_getter(d));
+    }
+
+    template <class D>
+    self& def_readwrite_impl(
+        char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
+    {
+        return this->add_static_property(name, python::make_getter(d), python::make_setter(d));
+    }
+
+    template <class DefVisitor>
+    inline void initialize(DefVisitor const& i)
+    {
+        metadata::register_(); // set up runtime metadata/conversions
+        
+        typedef typename metadata::holder holder;
+        this->set_instance_size( objects::additional_instance_size<holder>::value );
+        
+        this->def(i);
+    }
+    
+    inline void initialize(no_init_t)
+    {
+        metadata::register_(); // set up runtime metadata/conversions
+        this->def_no_init();
+    }
+    
+    //
+    // These two overloads discriminate between def() as applied to a
+    // generic visitor and everything else.
+    //
+    // @group def_impl {
+    template <class T, class Helper, class LeafVisitor, class Visitor>
+    inline void def_impl(
+        T*
+      , char const* name
+      , LeafVisitor
+      , Helper const& helper
+      , def_visitor<Visitor> const* v
+    )
+    {
+        v->visit(*this, name,  helper);
+    }
+
+    template <class T, class Fn, class Helper>
+    inline void def_impl(
+        T*
+      , char const* name
+      , Fn fn
+      , Helper const& helper
+      , ...
+    )
+    {
+        objects::add_to_namespace(
+            *this
+          , name
+          , make_function(
+                fn
+              , helper.policies()
+              , helper.keywords()
+              , detail::get_signature(fn, (T*)0)
+            )
+          , helper.doc()
+        );
+
+        this->def_default(name, fn, helper, mpl::bool_<Helper::has_default_implementation>());
+    }
+    // }
+
+    //
+    // These two overloads handle the definition of default
+    // implementation overloads for virtual functions. The second one
+    // handles the case where no default implementation was specified.
+    //
+    // @group def_default {
+    template <class Fn, class Helper>
+    inline void def_default(
+        char const* name
+        , Fn
+        , Helper const& helper
+        , mpl::bool_<true>)
+    {
+        detail::error::virtual_function_default<W,Fn>::must_be_derived_class_member(
+            helper.default_implementation());
+            
+        objects::add_to_namespace(
+            *this, name,
+            make_function(
+                helper.default_implementation(), helper.policies(), helper.keywords())
+            );
+    }
+    
+    template <class Fn, class Helper>
+    inline void def_default(char const*, Fn, Helper const&, mpl::bool_<false>)
+    { }
+    // }
+    
+    //
+    // These two overloads discriminate between def() as applied to
+    // regular functions and def() as applied to the result of
+    // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
+    // discriminate.
+    //
+    // @group def_maybe_overloads {
+    template <class OverloadsT, class SigT>
+    void def_maybe_overloads(
+        char const* name
+        , SigT sig
+        , OverloadsT const& overloads
+        , detail::overloads_base const*)
+
+    {
+        //  convert sig to a type_list (see detail::get_signature in signature.hpp)
+        //  before calling detail::define_with_defaults.
+        detail::define_with_defaults(
+            name, overloads, *this, detail::get_signature(sig));
+    }
+
+    template <class Fn, class A1>
+    void def_maybe_overloads(
+        char const* name
+        , Fn fn
+        , A1 const& a1
+        , ...)
+    {
+        this->def_impl(
+            detail::unwrap_wrapper((W*)0)
+          , name
+          , fn
+          , detail::def_helper<A1>(a1)
+          , &fn
+        );
+
+    }
+    // }
+};
+
+
+//
+// implementations
+//
+
+template <class W, class X1, class X2, class X3>
+inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc)
+    : base(name, id_vector::size, id_vector().ids, doc)
+{
+    this->initialize(init<>());
+//  select_holder::assert_default_constructible();
+}
+
+template <class W, class X1, class X2, class X3>
+inline class_<W,X1,X2,X3>::class_(char const* name, no_init_t)
+    : base(name, id_vector::size, id_vector().ids)
+{
+    this->initialize(no_init);
+}
+
+template <class W, class X1, class X2, class X3>
+inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
+    : base(name, id_vector::size, id_vector().ids, doc)
+{
+    this->initialize(no_init);
+}
+
+}} // namespace boost::python
+
+# undef BOOST_PYTHON_DATA_MEMBER_HELPER
+# undef BOOST_PYTHON_YES_DATA_MEMBER
+# undef BOOST_PYTHON_NO_DATA_MEMBER
+# undef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
+
+#endif // CLASS_DWA200216_HPP