Skip to content

Commit 6e06ff0

Browse files
committed
Automatic class def_init(), abstract class __init__ errors
Fixed line endings Suppressed warnings [SVN r14828]
1 parent c5ee39f commit 6e06ff0

31 files changed

+1045
-115
lines changed

include/boost/python/args.hpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,25 @@
1616
# include <boost/preprocessor/cat.hpp>
1717
# include <boost/preprocessor/iterate.hpp>
1818

19+
namespace boost { namespace python {
20+
21+
enum no_init_t { no_init };
22+
23+
namespace detail
24+
{
25+
template <class Args>
26+
struct args_base {};
27+
}
28+
}}
29+
1930
# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245
2031

2132
namespace boost { namespace python {
2233

2334
// A type list for specifying arguments
2435
template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) >
25-
struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type
36+
struct args : detail::args_base<args<BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A)> >
37+
, boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type
2638
{};
2739

2840
}} // namespace boost::python
@@ -36,7 +48,7 @@ struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_AR
3648
namespace boost { namespace python {
3749

3850
template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) >
39-
struct args
51+
struct args : detail::args_base<args<BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A)> >
4052
{};
4153

4254
}} // namespace boost::python

include/boost/python/class.hpp

Lines changed: 100 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
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

3233
namespace 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
>
7679
class 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
262289
template <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+
275319
template <class T, class X1, class X2, class X3>
276320
inline 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

289344
template <class T, class X1, class X2, class X3>
290345
inline class_<T,X1,X2,X3>& class_<T,X1,X2,X3>::add_property(char const* name, object const& fget)

0 commit comments

Comments
 (0)