ossrv_pub/boost_apis/boost/python/class.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright David Abrahams 2002.
       
     2 // Distributed under the Boost Software License, Version 1.0. (See
       
     3 // accompanying file LICENSE_1_0.txt or copy at
       
     4 // http://www.boost.org/LICENSE_1_0.txt)
       
     5 #ifndef CLASS_DWA200216_HPP
       
     6 # define CLASS_DWA200216_HPP
       
     7 
       
     8 # include <boost/python/detail/prefix.hpp>
       
     9 
       
    10 # include <boost/noncopyable.hpp>
       
    11 
       
    12 # include <boost/python/class_fwd.hpp>
       
    13 # include <boost/python/object/class.hpp>
       
    14 
       
    15 # include <boost/python/object.hpp>
       
    16 # include <boost/python/type_id.hpp>
       
    17 # include <boost/python/data_members.hpp>
       
    18 # include <boost/python/make_function.hpp>
       
    19 # include <boost/python/signature.hpp>
       
    20 # include <boost/python/init.hpp>
       
    21 # include <boost/python/args_fwd.hpp>
       
    22 
       
    23 # include <boost/python/object/class_metadata.hpp>
       
    24 # include <boost/python/object/pickle_support.hpp>
       
    25 # include <boost/python/object/add_to_namespace.hpp>
       
    26 
       
    27 # include <boost/python/detail/overloads_fwd.hpp>
       
    28 # include <boost/python/detail/operator_id.hpp>
       
    29 # include <boost/python/detail/def_helper.hpp>
       
    30 # include <boost/python/detail/force_instantiate.hpp>
       
    31 # include <boost/python/detail/unwrap_type_id.hpp>
       
    32 # include <boost/python/detail/unwrap_wrapper.hpp>
       
    33 
       
    34 # include <boost/type_traits/is_same.hpp>
       
    35 # include <boost/type_traits/is_member_function_pointer.hpp>
       
    36 # include <boost/type_traits/is_polymorphic.hpp>
       
    37 
       
    38 # include <boost/mpl/size.hpp>
       
    39 # include <boost/mpl/for_each.hpp>
       
    40 # include <boost/mpl/bool.hpp>
       
    41 # include <boost/mpl/not.hpp>
       
    42 
       
    43 # include <boost/detail/workaround.hpp>
       
    44 
       
    45 # if BOOST_WORKAROUND(__MWERKS__, <= 0x3004)                        \
       
    46     /* pro9 reintroduced the bug */                                 \
       
    47     || (BOOST_WORKAROUND(__MWERKS__, > 0x3100)                      \
       
    48         && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3201)))   \
       
    49     || BOOST_WORKAROUND(__GNUC__, < 3)
       
    50 
       
    51 #  define BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING 1
       
    52 
       
    53 # endif
       
    54 
       
    55 # ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
       
    56 #  include <boost/mpl/and.hpp>
       
    57 #  include <boost/type_traits/is_member_pointer.hpp>
       
    58 # endif
       
    59 
       
    60 namespace boost { namespace python {
       
    61 
       
    62 template <class DerivedVisitor> class def_visitor;
       
    63 
       
    64 enum no_init_t { no_init };
       
    65 
       
    66 namespace detail
       
    67 {
       
    68   // This function object is used with mpl::for_each to write the id
       
    69   // of the type a pointer to which is passed as its 2nd compile-time
       
    70   // argument. into the iterator pointed to by its runtime argument
       
    71   struct write_type_id
       
    72   {
       
    73       write_type_id(type_info**p) : p(p) {}
       
    74 
       
    75       // Here's the runtime behavior
       
    76       template <class T>
       
    77       void operator()(T*) const
       
    78       {
       
    79           *(*p)++ = type_id<T>();
       
    80       }
       
    81 
       
    82       type_info** p;
       
    83   };
       
    84 
       
    85   template <class T>
       
    86   struct is_data_member_pointer
       
    87       : mpl::and_<
       
    88             is_member_pointer<T>
       
    89           , mpl::not_<is_member_function_pointer<T> >
       
    90         >
       
    91   {};
       
    92   
       
    93 # ifdef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
       
    94 #  define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , detail::is_data_member_pointer<D>()
       
    95 #  define BOOST_PYTHON_YES_DATA_MEMBER , mpl::true_
       
    96 #  define BOOST_PYTHON_NO_DATA_MEMBER , mpl::false_
       
    97 # elif defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
       
    98 #  define BOOST_PYTHON_DATA_MEMBER_HELPER(D) , 0
       
    99 #  define BOOST_PYTHON_YES_DATA_MEMBER , int
       
   100 #  define BOOST_PYTHON_NO_DATA_MEMBER , ...
       
   101 # else 
       
   102 #  define BOOST_PYTHON_DATA_MEMBER_HELPER(D)
       
   103 #  define BOOST_PYTHON_YES_DATA_MEMBER
       
   104 #  define BOOST_PYTHON_NO_DATA_MEMBER
       
   105 # endif
       
   106   
       
   107   namespace error
       
   108   {
       
   109     //
       
   110     // A meta-assertion mechanism which prints nice error messages and
       
   111     // backtraces on lots of compilers. Usage:
       
   112     //
       
   113     //      assertion<C>::failed
       
   114     //
       
   115     // where C is an MPL metafunction class
       
   116     //
       
   117     
       
   118     template <class C> struct assertion_failed { };
       
   119     template <class C> struct assertion_ok { typedef C failed; };
       
   120 
       
   121     template <class C>
       
   122     struct assertion
       
   123         : mpl::if_<C, assertion_ok<C>, assertion_failed<C> >::type
       
   124     {};
       
   125 
       
   126     //
       
   127     // Checks for validity of arguments used to define virtual
       
   128     // functions with default implementations.
       
   129     //
       
   130     
       
   131     template <class Default>
       
   132     void not_a_derived_class_member(Default) {}
       
   133     
       
   134     template <class T, class Fn>
       
   135     struct virtual_function_default
       
   136     {
       
   137         template <class Default>
       
   138         static void
       
   139         must_be_derived_class_member(Default const&)
       
   140         {
       
   141             typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
       
   142 # if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
       
   143             typedef typename assertion<is_polymorphic<T> >::failed test1;
       
   144 # endif 
       
   145             typedef typename assertion<is_member_function_pointer<Fn> >::failed test2;
       
   146             not_a_derived_class_member<Default>(Fn());
       
   147         }
       
   148     };
       
   149   }
       
   150 }
       
   151 
       
   152 // This is the primary mechanism through which users will expose
       
   153 // C++ classes to Python.
       
   154 template <
       
   155     class W // class being wrapped
       
   156     , class X1 // = detail::not_specified
       
   157     , class X2 // = detail::not_specified
       
   158     , class X3 // = detail::not_specified
       
   159     >
       
   160 class class_ : public objects::class_base
       
   161 {
       
   162  public: // types
       
   163     typedef objects::class_base base;
       
   164     typedef class_<W,X1,X2,X3> self;
       
   165     typedef typename objects::class_metadata<W,X1,X2,X3> metadata;
       
   166     typedef W wrapped_type;
       
   167     
       
   168  private: // types
       
   169 
       
   170     // A helper class which will contain an array of id objects to be
       
   171     // passed to the base class constructor
       
   172     struct id_vector
       
   173     {
       
   174         typedef typename metadata::bases bases;
       
   175         
       
   176         id_vector()
       
   177         {
       
   178             // Stick the derived class id into the first element of the array
       
   179             ids[0] = detail::unwrap_type_id((W*)0, (W*)0);
       
   180 
       
   181             // Write the rest of the elements into succeeding positions.
       
   182             type_info* p = ids + 1;
       
   183             mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer<mpl::_>*)0);
       
   184         }
       
   185 
       
   186         BOOST_STATIC_CONSTANT(
       
   187             std::size_t, size = mpl::size<bases>::value + 1);
       
   188         type_info ids[size];
       
   189     };
       
   190     friend struct id_vector;
       
   191 
       
   192  public: // constructors
       
   193     
       
   194     // Construct with the class name, with or without docstring, and default __init__() function
       
   195     class_(char const* name, char const* doc = 0);
       
   196 
       
   197     // Construct with class name, no docstring, and an uncallable __init__ function
       
   198     class_(char const* name, no_init_t);
       
   199 
       
   200     // Construct with class name, docstring, and an uncallable __init__ function
       
   201     class_(char const* name, char const* doc, no_init_t);
       
   202 
       
   203     // Construct with class name and init<> function
       
   204     template <class DerivedT>
       
   205     inline class_(char const* name, init_base<DerivedT> const& i)
       
   206         : base(name, id_vector::size, id_vector().ids)
       
   207     {
       
   208         this->initialize(i);
       
   209     }
       
   210 
       
   211     // Construct with class name, docstring and init<> function
       
   212     template <class DerivedT>
       
   213     inline class_(char const* name, char const* doc, init_base<DerivedT> const& i)
       
   214         : base(name, id_vector::size, id_vector().ids, doc)
       
   215     {
       
   216         this->initialize(i);
       
   217     }
       
   218 
       
   219  public: // member functions
       
   220     
       
   221     // Generic visitation
       
   222     template <class Derived>
       
   223     self& def(def_visitor<Derived> const& visitor)
       
   224     {
       
   225         visitor.visit(*this);
       
   226         return *this;
       
   227     }
       
   228 
       
   229     // Wrap a member function or a non-member function which can take
       
   230     // a T, T cv&, or T cv* as its first parameter, a callable
       
   231     // python object, or a generic visitor.
       
   232     template <class F>
       
   233     self& def(char const* name, F f)
       
   234     {
       
   235         this->def_impl(
       
   236             detail::unwrap_wrapper((W*)0)
       
   237           , name, f, detail::def_helper<char const*>(0), &f);
       
   238         return *this;
       
   239     }
       
   240 
       
   241     template <class A1, class A2>
       
   242     self& def(char const* name, A1 a1, A2 const& a2)
       
   243     {
       
   244         this->def_maybe_overloads(name, a1, a2, &a2);
       
   245         return *this;
       
   246     }
       
   247 
       
   248     template <class Fn, class A1, class A2>
       
   249     self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2)
       
   250     {
       
   251         //  The arguments are definitely:
       
   252         //      def(name, function, policy, doc_string)
       
   253         //      def(name, function, doc_string, policy)
       
   254 
       
   255         this->def_impl(
       
   256             detail::unwrap_wrapper((W*)0)
       
   257           , name, fn
       
   258           , detail::def_helper<A1,A2>(a1,a2)
       
   259           , &fn);
       
   260 
       
   261         return *this;
       
   262     }
       
   263 
       
   264     template <class Fn, class A1, class A2, class A3>
       
   265     self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3)
       
   266     {
       
   267         this->def_impl(
       
   268             detail::unwrap_wrapper((W*)0)
       
   269           , name, fn
       
   270           , detail::def_helper<A1,A2,A3>(a1,a2,a3)
       
   271           , &fn);
       
   272 
       
   273         return *this;
       
   274     }
       
   275 
       
   276     //
       
   277     // Data member access
       
   278     //
       
   279     template <class D>
       
   280     self& def_readonly(char const* name, D const& d, char const* doc=0)
       
   281     {
       
   282         return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
       
   283     }
       
   284 
       
   285     template <class D>
       
   286     self& def_readwrite(char const* name, D const& d, char const* doc=0)
       
   287     {
       
   288         return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
       
   289     }
       
   290     
       
   291     template <class D>
       
   292     self& def_readonly(char const* name, D& d, char const* doc=0)
       
   293     {
       
   294         return this->def_readonly_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
       
   295     }
       
   296 
       
   297     template <class D>
       
   298     self& def_readwrite(char const* name, D& d, char const* doc=0)
       
   299     {
       
   300         return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
       
   301     }
       
   302 
       
   303     // Property creation
       
   304 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
       
   305     template <class Get>
       
   306     self& add_property(char const* name, Get fget, char const* docstr = 0)
       
   307     {
       
   308         base::add_property(name, this->make_getter(fget), docstr);
       
   309         return *this;
       
   310     }
       
   311 
       
   312     template <class Get, class Set>
       
   313     self& add_property(char const* name, Get fget, Set fset, char const* docstr = 0)
       
   314     {
       
   315         base::add_property(
       
   316             name, this->make_getter(fget), this->make_setter(fset), docstr);
       
   317         return *this;
       
   318     }
       
   319 # else
       
   320  private:
       
   321     template <class Get>
       
   322     self& add_property_impl(char const* name, Get fget, char const* docstr, int)
       
   323     {
       
   324         base::add_property(name, this->make_getter(fget), docstr);
       
   325         return *this;
       
   326     }
       
   327 
       
   328     template <class Get, class Set>
       
   329     self& add_property_impl(char const* name, Get fget, Set fset, ...)
       
   330     {
       
   331         base::add_property(
       
   332             name, this->make_getter(fget), this->make_setter(fset), 0);
       
   333         return *this;
       
   334     }
       
   335 
       
   336  public:    
       
   337     template <class Get>
       
   338     self& add_property(char const* name, Get fget)
       
   339     {
       
   340         base::add_property(name, this->make_getter(fget), 0);
       
   341         return *this;
       
   342     }
       
   343 
       
   344     template <class Get, class DocStrOrSet>
       
   345     self& add_property(char const* name, Get fget, DocStrOrSet docstr_or_set)
       
   346     {
       
   347         this->add_property_impl(name, this->make_getter(fget), docstr_or_set, 0);
       
   348         return *this;
       
   349     }
       
   350 
       
   351     template <class Get, class Set>
       
   352     self&
       
   353     add_property(char const* name, Get fget, Set fset, char const* docstr)
       
   354     {
       
   355         base::add_property(
       
   356             name, this->make_getter(fget), this->make_setter(fset), docstr);
       
   357         return *this;
       
   358     }
       
   359 # endif
       
   360         
       
   361     template <class Get>
       
   362     self& add_static_property(char const* name, Get fget)
       
   363     {
       
   364         base::add_static_property(name, object(fget));
       
   365         return *this;
       
   366     }
       
   367 
       
   368     template <class Get, class Set>
       
   369     self& add_static_property(char const* name, Get fget, Set fset)
       
   370     {
       
   371         base::add_static_property(name, object(fget), object(fset));
       
   372         return *this;
       
   373     }
       
   374         
       
   375     template <class U>
       
   376     self& setattr(char const* name, U const& x)
       
   377     {
       
   378         this->base::setattr(name, object(x));
       
   379         return *this;
       
   380     }
       
   381 
       
   382     // Pickle support
       
   383     template <typename PickleSuiteType>
       
   384     self& def_pickle(PickleSuiteType const& x)
       
   385     {
       
   386       error_messages::must_be_derived_from_pickle_suite(x);
       
   387       detail::pickle_suite_finalize<PickleSuiteType>::register_(
       
   388         *this,
       
   389         &PickleSuiteType::getinitargs,
       
   390         &PickleSuiteType::getstate,
       
   391         &PickleSuiteType::setstate,
       
   392         PickleSuiteType::getstate_manages_dict());
       
   393       return *this;
       
   394     }
       
   395 
       
   396     self& enable_pickling()
       
   397     {
       
   398         this->base::enable_pickling_(false);
       
   399         return *this;
       
   400     }
       
   401 
       
   402     self& staticmethod(char const* name)
       
   403     {
       
   404         this->make_method_static(name);
       
   405         return *this;
       
   406     }
       
   407  private: // helper functions
       
   408 
       
   409     // Builds a method for this class around the given [member]
       
   410     // function pointer or object, appropriately adjusting the type of
       
   411     // the first signature argument so that if f is a member of a
       
   412     // (possibly not wrapped) base class of T, an lvalue argument of
       
   413     // type T will be required.
       
   414     //
       
   415     // @group PropertyHelpers {
       
   416     template <class F>
       
   417     object make_getter(F f)
       
   418     {
       
   419         typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
       
   420         
       
   421         return this->make_fn_impl(
       
   422             detail::unwrap_wrapper((W*)0)
       
   423           , f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
       
   424         );
       
   425     }
       
   426     
       
   427     template <class F>
       
   428     object make_setter(F f)
       
   429     {
       
   430         typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
       
   431         
       
   432         return this->make_fn_impl(
       
   433             detail::unwrap_wrapper((W*)0)
       
   434           , f, is_obj_or_proxy(), (int*)0, detail::is_data_member_pointer<F>()
       
   435         );
       
   436     }
       
   437     
       
   438     template <class T, class F>
       
   439     object make_fn_impl(T*, F const& f, mpl::false_, void*, mpl::false_)
       
   440     {
       
   441         return python::make_function(f, default_call_policies(), detail::get_signature(f, (T*)0));
       
   442     }
       
   443 
       
   444     template <class T, class D, class B>
       
   445     object make_fn_impl(T*, D B::*pm_, mpl::false_, char*, mpl::true_)
       
   446     {
       
   447         D T::*pm = pm_;
       
   448         return python::make_getter(pm);
       
   449     }
       
   450 
       
   451     template <class T, class D, class B>
       
   452     object make_fn_impl(T*, D B::*pm_, mpl::false_, int*, mpl::true_)
       
   453     {
       
   454         D T::*pm = pm_;
       
   455         return python::make_setter(pm);
       
   456     }
       
   457 
       
   458     template <class T, class F>
       
   459     object make_fn_impl(T*, F const& x, mpl::true_, void*, mpl::false_)
       
   460     {
       
   461         return x;
       
   462     }
       
   463     // }
       
   464     
       
   465     template <class D, class B>
       
   466     self& def_readonly_impl(
       
   467         char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
       
   468     {
       
   469         return this->add_property(name, pm_, doc);
       
   470     }
       
   471 
       
   472     template <class D, class B>
       
   473     self& def_readwrite_impl(
       
   474         char const* name, D B::*pm_, char const* doc BOOST_PYTHON_YES_DATA_MEMBER)
       
   475     {
       
   476         return this->add_property(name, pm_, pm_, doc);
       
   477     }
       
   478 
       
   479     template <class D>
       
   480     self& def_readonly_impl(
       
   481         char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
       
   482     {
       
   483         return this->add_static_property(name, python::make_getter(d));
       
   484     }
       
   485 
       
   486     template <class D>
       
   487     self& def_readwrite_impl(
       
   488         char const* name, D& d, char const* BOOST_PYTHON_NO_DATA_MEMBER)
       
   489     {
       
   490         return this->add_static_property(name, python::make_getter(d), python::make_setter(d));
       
   491     }
       
   492 
       
   493     template <class DefVisitor>
       
   494     inline void initialize(DefVisitor const& i)
       
   495     {
       
   496         metadata::register_(); // set up runtime metadata/conversions
       
   497         
       
   498         typedef typename metadata::holder holder;
       
   499         this->set_instance_size( objects::additional_instance_size<holder>::value );
       
   500         
       
   501         this->def(i);
       
   502     }
       
   503     
       
   504     inline void initialize(no_init_t)
       
   505     {
       
   506         metadata::register_(); // set up runtime metadata/conversions
       
   507         this->def_no_init();
       
   508     }
       
   509     
       
   510     //
       
   511     // These two overloads discriminate between def() as applied to a
       
   512     // generic visitor and everything else.
       
   513     //
       
   514     // @group def_impl {
       
   515     template <class T, class Helper, class LeafVisitor, class Visitor>
       
   516     inline void def_impl(
       
   517         T*
       
   518       , char const* name
       
   519       , LeafVisitor
       
   520       , Helper const& helper
       
   521       , def_visitor<Visitor> const* v
       
   522     )
       
   523     {
       
   524         v->visit(*this, name,  helper);
       
   525     }
       
   526 
       
   527     template <class T, class Fn, class Helper>
       
   528     inline void def_impl(
       
   529         T*
       
   530       , char const* name
       
   531       , Fn fn
       
   532       , Helper const& helper
       
   533       , ...
       
   534     )
       
   535     {
       
   536         objects::add_to_namespace(
       
   537             *this
       
   538           , name
       
   539           , make_function(
       
   540                 fn
       
   541               , helper.policies()
       
   542               , helper.keywords()
       
   543               , detail::get_signature(fn, (T*)0)
       
   544             )
       
   545           , helper.doc()
       
   546         );
       
   547 
       
   548         this->def_default(name, fn, helper, mpl::bool_<Helper::has_default_implementation>());
       
   549     }
       
   550     // }
       
   551 
       
   552     //
       
   553     // These two overloads handle the definition of default
       
   554     // implementation overloads for virtual functions. The second one
       
   555     // handles the case where no default implementation was specified.
       
   556     //
       
   557     // @group def_default {
       
   558     template <class Fn, class Helper>
       
   559     inline void def_default(
       
   560         char const* name
       
   561         , Fn
       
   562         , Helper const& helper
       
   563         , mpl::bool_<true>)
       
   564     {
       
   565         detail::error::virtual_function_default<W,Fn>::must_be_derived_class_member(
       
   566             helper.default_implementation());
       
   567             
       
   568         objects::add_to_namespace(
       
   569             *this, name,
       
   570             make_function(
       
   571                 helper.default_implementation(), helper.policies(), helper.keywords())
       
   572             );
       
   573     }
       
   574     
       
   575     template <class Fn, class Helper>
       
   576     inline void def_default(char const*, Fn, Helper const&, mpl::bool_<false>)
       
   577     { }
       
   578     // }
       
   579     
       
   580     //
       
   581     // These two overloads discriminate between def() as applied to
       
   582     // regular functions and def() as applied to the result of
       
   583     // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to
       
   584     // discriminate.
       
   585     //
       
   586     // @group def_maybe_overloads {
       
   587     template <class OverloadsT, class SigT>
       
   588     void def_maybe_overloads(
       
   589         char const* name
       
   590         , SigT sig
       
   591         , OverloadsT const& overloads
       
   592         , detail::overloads_base const*)
       
   593 
       
   594     {
       
   595         //  convert sig to a type_list (see detail::get_signature in signature.hpp)
       
   596         //  before calling detail::define_with_defaults.
       
   597         detail::define_with_defaults(
       
   598             name, overloads, *this, detail::get_signature(sig));
       
   599     }
       
   600 
       
   601     template <class Fn, class A1>
       
   602     void def_maybe_overloads(
       
   603         char const* name
       
   604         , Fn fn
       
   605         , A1 const& a1
       
   606         , ...)
       
   607     {
       
   608         this->def_impl(
       
   609             detail::unwrap_wrapper((W*)0)
       
   610           , name
       
   611           , fn
       
   612           , detail::def_helper<A1>(a1)
       
   613           , &fn
       
   614         );
       
   615 
       
   616     }
       
   617     // }
       
   618 };
       
   619 
       
   620 
       
   621 //
       
   622 // implementations
       
   623 //
       
   624 
       
   625 template <class W, class X1, class X2, class X3>
       
   626 inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc)
       
   627     : base(name, id_vector::size, id_vector().ids, doc)
       
   628 {
       
   629     this->initialize(init<>());
       
   630 //  select_holder::assert_default_constructible();
       
   631 }
       
   632 
       
   633 template <class W, class X1, class X2, class X3>
       
   634 inline class_<W,X1,X2,X3>::class_(char const* name, no_init_t)
       
   635     : base(name, id_vector::size, id_vector().ids)
       
   636 {
       
   637     this->initialize(no_init);
       
   638 }
       
   639 
       
   640 template <class W, class X1, class X2, class X3>
       
   641 inline class_<W,X1,X2,X3>::class_(char const* name, char const* doc, no_init_t)
       
   642     : base(name, id_vector::size, id_vector().ids, doc)
       
   643 {
       
   644     this->initialize(no_init);
       
   645 }
       
   646 
       
   647 }} // namespace boost::python
       
   648 
       
   649 # undef BOOST_PYTHON_DATA_MEMBER_HELPER
       
   650 # undef BOOST_PYTHON_YES_DATA_MEMBER
       
   651 # undef BOOST_PYTHON_NO_DATA_MEMBER
       
   652 # undef BOOST_PYTHON_NO_MEMBER_POINTER_ORDERING
       
   653 
       
   654 #endif // CLASS_DWA200216_HPP