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 MAKE_INSTANCE_DWA200296_HPP 6 # define MAKE_INSTANCE_DWA200296_HPP 7 8 # include <boost/python/detail/prefix.hpp> 9 # include <boost/python/object/instance.hpp> 10 # include <boost/python/converter/registered.hpp> 11 # include <boost/python/detail/decref_guard.hpp> 12 # include <boost/python/detail/type_traits.hpp> 13 # include <boost/python/detail/none.hpp> 14 # include <boost/mpl/assert.hpp> 15 # include <boost/mpl/or.hpp> 16 17 namespace boost { namespace python { namespace objects { 18 19 template <class T, class Holder, class Derived> 20 struct make_instance_impl 21 { 22 typedef objects::instance<Holder> instance_t; 23 24 template <class Arg> executeboost::python::objects::make_instance_impl25 static inline PyObject* execute(Arg& x) 26 { 27 BOOST_MPL_ASSERT((mpl::or_<boost::python::detail::is_class<T>, 28 boost::python::detail::is_union<T> >)); 29 30 PyTypeObject* type = Derived::get_class_object(x); 31 32 if (type == 0) 33 return python::detail::none(); 34 35 PyObject* raw_result = type->tp_alloc( 36 type, objects::additional_instance_size<Holder>::value); 37 38 if (raw_result != 0) 39 { 40 python::detail::decref_guard protect(raw_result); 41 42 instance_t* instance = (instance_t*)raw_result; 43 44 // construct the new C++ object and install the pointer 45 // in the Python object. 46 Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result); 47 48 // Note the position of the internally-stored Holder, 49 // for the sake of destruction 50 Py_SIZE(instance) = offsetof(instance_t, storage); 51 52 // Release ownership of the python object 53 protect.cancel(); 54 } 55 return raw_result; 56 } 57 }; 58 59 60 template <class T, class Holder> 61 struct make_instance 62 : make_instance_impl<T, Holder, make_instance<T,Holder> > 63 { 64 template <class U> get_class_objectboost::python::objects::make_instance65 static inline PyTypeObject* get_class_object(U&) 66 { 67 return converter::registered<T>::converters.get_class_object(); 68 } 69 constructboost::python::objects::make_instance70 static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper<T const> x) 71 { 72 return new (storage) Holder(instance, x); 73 } 74 }; 75 76 77 }}} // namespace boost::python::object 78 79 #endif // MAKE_INSTANCE_DWA200296_HPP 80