to_python_indirect.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 TO_PYTHON_INDIRECT_DWA200221_HPP
  6. # define TO_PYTHON_INDIRECT_DWA200221_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/object/pointer_holder.hpp>
  9. # include <boost/python/object/make_ptr_instance.hpp>
  10. # include <boost/python/detail/none.hpp>
  11. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  12. # include <boost/python/converter/pytype_function.hpp>
  13. #endif
  14. # include <boost/python/refcount.hpp>
  15. # include <boost/python/detail/type_traits.hpp>
  16. # if defined(__ICL) && __ICL < 600
  17. # include <boost/shared_ptr.hpp>
  18. # else
  19. # include <memory>
  20. # endif
  21. namespace boost { namespace python {
  22. template <class T, class MakeHolder>
  23. struct to_python_indirect
  24. {
  25. template <class U>
  26. inline PyObject*
  27. operator()(U const& ref) const
  28. {
  29. return this->execute(const_cast<U&>(ref), detail::is_pointer<U>());
  30. }
  31. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  32. inline PyTypeObject const*
  33. get_pytype()const
  34. {
  35. return converter::registered_pytype<T>::get_pytype();
  36. }
  37. #endif
  38. private:
  39. template <class U>
  40. inline PyObject* execute(U* ptr, detail::true_) const
  41. {
  42. // No special NULL treatment for references
  43. if (ptr == 0)
  44. return python::detail::none();
  45. else
  46. return this->execute(*ptr, detail::false_());
  47. }
  48. template <class U>
  49. inline PyObject* execute(U const& x, detail::false_) const
  50. {
  51. U* const p = &const_cast<U&>(x);
  52. if (detail::is_polymorphic<U>::value)
  53. {
  54. if (PyObject* o = detail::wrapper_base_::owner(p))
  55. return incref(o);
  56. }
  57. return MakeHolder::execute(p);
  58. }
  59. };
  60. //
  61. // implementations
  62. //
  63. namespace detail
  64. {
  65. struct make_owning_holder
  66. {
  67. template <class T>
  68. static PyObject* execute(T* p)
  69. {
  70. // can't use auto_ptr with Intel 5 and VC6 Dinkum library
  71. // for some reason. We get link errors against the auto_ptr
  72. // copy constructor.
  73. # if defined(__ICL) && __ICL < 600
  74. typedef boost::shared_ptr<T> smart_pointer;
  75. # elif defined(BOOST_NO_CXX11_SMART_PTR)
  76. typedef std::auto_ptr<T> smart_pointer;
  77. # else
  78. typedef std::unique_ptr<T> smart_pointer;
  79. # endif
  80. typedef objects::pointer_holder<smart_pointer, T> holder_t;
  81. smart_pointer ptr(const_cast<T*>(p));
  82. return objects::make_ptr_instance<T, holder_t>::execute(ptr);
  83. }
  84. };
  85. struct make_reference_holder
  86. {
  87. template <class T>
  88. static PyObject* execute(T* p)
  89. {
  90. typedef objects::pointer_holder<T*, T> holder_t;
  91. T* q = const_cast<T*>(p);
  92. return objects::make_ptr_instance<T, holder_t>::execute(q);
  93. }
  94. };
  95. }
  96. }} // namespace boost::python
  97. #endif // TO_PYTHON_INDIRECT_DWA200221_HPP