make_ptr_instance.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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/type_traits/is_polymorphic.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. return new (storage) Holder(x);
  22. }
  23. template <class Ptr>
  24. static inline PyTypeObject* get_class_object(Ptr const& x)
  25. {
  26. return get_class_object_impl(get_pointer(x));
  27. }
  28. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  29. static inline PyTypeObject const* get_pytype()
  30. {
  31. return converter::registered<T>::converters.get_class_object();
  32. }
  33. #endif
  34. private:
  35. template <class U>
  36. static inline PyTypeObject* get_class_object_impl(U const volatile* p)
  37. {
  38. if (p == 0)
  39. return 0; // means "return None".
  40. PyTypeObject* derived = get_derived_class_object(
  41. BOOST_DEDUCED_TYPENAME is_polymorphic<U>::type(), p);
  42. if (derived)
  43. return derived;
  44. return converter::registered<T>::converters.get_class_object();
  45. }
  46. template <class U>
  47. static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x)
  48. {
  49. converter::registration const* r = converter::registry::query(
  50. type_info(typeid(*get_pointer(x)))
  51. );
  52. return r ? r->m_class_object : 0;
  53. }
  54. template <class U>
  55. static inline PyTypeObject* get_derived_class_object(mpl::false_, U*)
  56. {
  57. return 0;
  58. }
  59. };
  60. }}} // namespace boost::python::object
  61. #endif // MAKE_PTR_INSTANCE_DWA200296_HPP