make_ptr_instance.hpp 2.2 KB

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