88
99# include < boost/python/object/instance.hpp>
1010# include < boost/python/converter/registered.hpp>
11+ # include < boost/python/detail/decref_guard.hpp>
1112
1213namespace boost { namespace python { namespace objects {
1314
14- struct decref_guard
15- {
16- decref_guard (PyObject* o) : obj(o) {}
17- ~decref_guard () { Py_XDECREF (obj); }
18- void cancel () { obj = 0 ; }
19- private:
20- PyObject* obj;
21- };
22-
23- template <class T , class Holder >
24- struct make_instance
15+ template <class T , class Holder , class Derived >
16+ struct make_instance_impl
2517{
2618 typedef objects::instance<Holder> instance_t ;
2719
2820 template <class Arg >
29- static PyObject* execute (Arg& x)
21+ static inline PyObject* execute (Arg& x)
3022 {
3123 BOOST_STATIC_ASSERT (is_class<T>::value);
32-
33- PyTypeObject* type = converter::registered<T>::converters. get_class_object ();
24+
25+ PyTypeObject* type = Derived:: get_class_object (x );
3426
3527 PyObject* raw_result = type->tp_alloc (
3628 type, objects::additional_instance_size<Holder>::value);
3729
3830 if (raw_result != 0 )
3931 {
40- decref_guard protect (raw_result);
32+ python::detail:: decref_guard protect (raw_result);
4133
4234 instance_t * instance = (instance_t *)raw_result;
4335
4436 // construct the new C++ object and install the pointer
4537 // in the Python object.
46- construct (instance, x)->install (raw_result);
38+ Derived:: construct (&instance-> storage , (PyObject*) instance, x)->install (raw_result);
4739
4840 // Note the position of the internally-stored Holder,
4941 // for the sake of destruction
@@ -54,23 +46,22 @@ struct make_instance
5446 }
5547 return raw_result;
5648 }
49+ };
5750
58- private:
59- // Kind of a hack to support code re-use. The first form is used
60- // to construct holders around pointers or smart pointers. The
61- // second form is used to construct holders around by-value
62- // returns. We have to pass a pointer to the owning Python object
63- // to the second form in order to make it forward the 2nd argument
64- // on to the constructor of its embedded T object.
65- template <class Arg >
66- static Holder* construct (instance_t * result, Arg& x)
51+
52+ template <class T , class Holder >
53+ struct make_instance
54+ : make_instance_impl<T, Holder, make_instance<T,Holder> >
55+ {
56+ template <class U >
57+ static inline PyTypeObject* get_class_object (U&)
6758 {
68- return new (( void *)&result-> storage ) Holder (x );
59+ return converter::registered<T>::converters. get_class_object ( );
6960 }
70-
71- static Holder* construct (instance_t * result , reference_wrapper<T const > x)
61+
62+ static inline Holder* construct (void * storage, PyObject* instance , reference_wrapper<T const > x)
7263 {
73- return new (( void *)&result-> storage ) Holder ((PyObject*)result , x);
64+ return new (storage) Holder (instance , x);
7465 }
7566};
7667
0 commit comments