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