2828# include < boost/python/make_function.hpp>
2929# include < boost/python/object/add_to_namespace.hpp>
3030# include < boost/python/detail/def_helper.hpp>
31+ # include < boost/python/detail/force_instantiate.hpp>
3132
3233namespace boost { namespace python {
3334
@@ -58,7 +59,9 @@ namespace detail
5859 template <class T , class Holder >
5960 static inline void register_copy_constructor (mpl::bool_t <false > const &, Holder*, object const &, T* = 0 )
6061 {
61- }
62+ }
63+
64+ template <class T > int assert_default_constructible (T const &);
6265}
6366
6467//
@@ -75,7 +78,8 @@ template <
7578 >
7679class class_ : public objects ::class_base
7780{
78- typedef objects::class_base base;
81+ private: // types
82+ typedef objects::class_base base;
7983
8084 typedef class_<T,X1,X2,X3> self;
8185 BOOST_STATIC_CONSTANT (bool , is_copyable = (!detail::has_noncopyable<X1,X2,X3>::value));
@@ -86,17 +90,67 @@ class class_ : public objects::class_base
8690 X3
8791 >::type>::type>::type held_type;
8892
93+ typedef objects::class_id class_id;
94+
95+ typedef typename detail::select_bases<X1
96+ , typename detail::select_bases<X2
97+ , typename boost::python::detail::select_bases<X3>::type
98+ >::type
99+ >::type bases;
100+
101+ // A helper class which will contain an array of id objects to be
102+ // passed to the base class constructor
103+ struct id_vector
104+ {
105+ typedef objects::class_id class_id;
106+ id_vector ()
107+ {
108+ // Stick the derived class id into the first element of the array
109+ ids[0 ] = type_id<T>();
110+
111+ // Write the rest of the elements into succeeding positions.
112+ class_id* p = ids + 1 ;
113+ mpl::for_each<bases, void , detail::write_type_id>::execute (&p);
114+ }
115+
116+ BOOST_STATIC_CONSTANT (
117+ std::size_t , size = mpl::size<bases>::value + 1 );
118+ class_id ids[size];
119+ };
120+ friend struct id_vector ;
121+
89122 public:
90123 // Automatically derive the class name - only works on some
91124 // compilers because type_info::name is sometimes mangled (gcc)
92- class_ ();
125+ class_ (); // With default-constructor init function
126+ class_ (no_init_t ); // With no init function
93127
94- // Construct with the class name. [ Would have used a default
95- // argument but gcc-2.95.2 choked on typeid(T).name() as a default
96- // parameter value]
128+ // Construct with the class name, with or without docstring, and default init() function
97129 class_ (char const * name, char const * doc = 0 );
98130
131+ // Construct with class name, no docstring, and no init() function
132+ class_ (char const * name, no_init_t );
133+
134+ // Construct with class name, docstring, and no init() function
135+ class_ (char const * name, char const * doc, no_init_t );
99136
137+ template <class InitArgs >
138+ inline class_ (char const * name, detail::args_base<InitArgs> const &)
139+ : base(name, id_vector::size, id_vector().ids)
140+ {
141+ this ->register_ ();
142+ this ->def_init (InitArgs ());
143+ }
144+
145+
146+ template <class InitArgs >
147+ inline class_ (char const * name, char const * doc, detail::args_base<InitArgs> const &, char const * initdoc = 0 )
148+ : base(name, id_vector::size, id_vector().ids, doc)
149+ {
150+ this ->register_ ();
151+ this ->def_init (InitArgs (), initdoc);
152+ }
153+
100154 // Wrap a member function or a non-member function which can take
101155 // a T, T cv&, or T cv* as its first parameter, or a callable
102156 // python object.
@@ -224,46 +278,17 @@ class class_ : public objects::class_base
224278 objects::add_to_namespace (*this , name, f, doc);
225279 }
226280
227- private: // types
228- typedef objects::class_id class_id;
229-
230- typedef typename detail::select_bases<X1
231- , typename detail::select_bases<X2
232- , typename boost::python::detail::select_bases<X3>::type
233- >::type
234- >::type bases;
235-
236- // A helper class which will contain an array of id objects to be
237- // passed to the base class constructor
238- struct id_vector
239- {
240- typedef objects::class_id class_id;
241- id_vector ()
242- {
243- // Stick the derived class id into the first element of the array
244- ids[0 ] = type_id<T>();
245-
246- // Write the rest of the elements into succeeding positions.
247- class_id* p = ids + 1 ;
248- mpl::for_each<bases, void , detail::write_type_id>::execute (&p);
249- }
250-
251- BOOST_STATIC_CONSTANT (
252- std::size_t , size = mpl::size<bases>::value + 1 );
253- class_id ids[size];
254- };
255- friend struct id_vector ;
281+ inline void register_ () const ;
256282};
257283
258284
259285//
260286// implementations
261287//
288+ // register converters
262289template <class T , class X1 , class X2 , class X3 >
263- inline class_<T,X1,X2,X3>::class_()
264- : base(typeid (T).name(), id_vector::size, id_vector().ids)
290+ inline void class_<T,X1,X2,X3>::register_() const
265291{
266- // register converters
267292 objects::register_class_from_python<T,bases>();
268293
269294 detail::register_copy_constructor<T>(
@@ -272,19 +297,49 @@ inline class_<T,X1,X2,X3>::class_()
272297 , *this );
273298}
274299
300+
301+
302+ template <class T , class X1 , class X2 , class X3 >
303+ inline class_<T,X1,X2,X3>::class_()
304+ : base(typeid (T).name(), id_vector::size, id_vector().ids)
305+ {
306+ this ->register_ ();
307+ detail::force_instantiate (sizeof (detail::assert_default_constructible (T ())));
308+ this ->def_init ();
309+ }
310+
311+ template <class T , class X1 , class X2 , class X3 >
312+ inline class_<T,X1,X2,X3>::class_(no_init_t )
313+ : base(typeid (T).name(), id_vector::size, id_vector().ids)
314+ {
315+ this ->register_ ();
316+ this ->def_no_init ();
317+ }
318+
275319template <class T , class X1 , class X2 , class X3 >
276320inline class_<T,X1,X2,X3>::class_(char const * name, char const * doc)
277321 : base(name, id_vector::size, id_vector().ids, doc)
278322{
279- // register converters
280- objects::register_class_from_python<T,bases>();
281-
282- detail::register_copy_constructor<T>(
283- mpl::bool_t <is_copyable>()
284- , objects::select_holder<T,held_type>((held_type*)0 ).get ()
285- , *this );
323+ this ->register_ ();
324+ detail::force_instantiate (sizeof (detail::assert_default_constructible (T ())));
325+ this ->def_init ();
326+ }
327+
328+ template <class T , class X1 , class X2 , class X3 >
329+ inline class_<T,X1,X2,X3>::class_(char const * name, no_init_t )
330+ : base(name, id_vector::size, id_vector().ids)
331+ {
332+ this ->register_ ();
333+ this ->def_no_init ();
286334}
287335
336+ template <class T , class X1 , class X2 , class X3 >
337+ inline class_<T,X1,X2,X3>::class_(char const * name, char const * doc, no_init_t )
338+ : base(name, id_vector::size, id_vector().ids, doc)
339+ {
340+ this ->register_ ();
341+ this ->def_no_init ();
342+ }
288343
289344template <class T , class X1 , class X2 , class X3 >
290345inline class_<T,X1,X2,X3>& class_<T,X1,X2,X3>::add_property(char const * name, object const & fget)
0 commit comments