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_PTR_INSTANCE_DWA200296_HPP 6 # define MAKE_PTR_INSTANCE_DWA200296_HPP 7 8 # include <boost/python/object/make_instance.hpp> 9 # include <boost/python/converter/registry.hpp> 10 # include <boost/python/detail/type_traits.hpp> 11 # include <boost/get_pointer.hpp> 12 # include <boost/detail/workaround.hpp> 13 # include <typeinfo> 14 15 namespace boost { namespace python { namespace objects { 16 17 template <class T, class Holder> 18 struct make_ptr_instance 19 : make_instance_impl<T, Holder, make_ptr_instance<T,Holder> > 20 { 21 template <class Arg> constructboost::python::objects::make_ptr_instance22 static inline Holder* construct(void* storage, PyObject*, Arg& x) 23 { 24 #if defined(BOOST_NO_CXX11_SMART_PTR) 25 return new (storage) Holder(x); 26 #else 27 return new (storage) Holder(std::move(x)); 28 #endif 29 } 30 31 template <class Ptr> get_class_objectboost::python::objects::make_ptr_instance32 static inline PyTypeObject* get_class_object(Ptr const& x) 33 { 34 return get_class_object_impl(get_pointer(x)); 35 } 36 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES get_pytypeboost::python::objects::make_ptr_instance37 static inline PyTypeObject const* get_pytype() 38 { 39 return converter::registered<T>::converters.get_class_object(); 40 } 41 #endif 42 private: 43 template <class U> get_class_object_implboost::python::objects::make_ptr_instance44 static inline PyTypeObject* get_class_object_impl(U const volatile* p) 45 { 46 if (p == 0) 47 return 0; // means "return None". 48 49 PyTypeObject* derived = get_derived_class_object( 50 BOOST_DEDUCED_TYPENAME boost::python::detail::is_polymorphic<U>::type(), p); 51 52 if (derived) 53 return derived; 54 return converter::registered<T>::converters.get_class_object(); 55 } 56 57 template <class U> get_derived_class_objectboost::python::objects::make_ptr_instance58 static inline PyTypeObject* get_derived_class_object(boost::python::detail::true_, U const volatile* x) 59 { 60 converter::registration const* r = converter::registry::query( 61 type_info(typeid(*x)) 62 ); 63 return r ? r->m_class_object : 0; 64 } 65 66 template <class U> get_derived_class_objectboost::python::objects::make_ptr_instance67 static inline PyTypeObject* get_derived_class_object(boost::python::detail::false_, U*) 68 { 69 return 0; 70 } 71 }; 72 73 74 }}} // namespace boost::python::object 75 76 #endif // MAKE_PTR_INSTANCE_DWA200296_HPP 77