to_python_indirect.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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/type_traits/is_pointer.hpp>
  16. # include <boost/type_traits/is_polymorphic.hpp>
  17. # include <boost/mpl/bool.hpp>
  18. # if defined(__ICL) && __ICL < 600
  19. # include <boost/shared_ptr.hpp>
  20. # else
  21. # include <memory>
  22. # endif
  23. namespace boost { namespace python {
  24. template <class T, class MakeHolder>
  25. struct to_python_indirect
  26. {
  27. template <class U>
  28. inline PyObject*
  29. operator()(U const& ref) const
  30. {
  31. return this->execute(const_cast<U&>(ref), is_pointer<U>());
  32. }
  33. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  34. inline PyTypeObject const*
  35. get_pytype()const
  36. {
  37. return converter::registered_pytype<T>::get_pytype();
  38. }
  39. #endif
  40. private:
  41. template <class U>
  42. inline PyObject* execute(U* ptr, mpl::true_) const
  43. {
  44. // No special NULL treatment for references
  45. if (ptr == 0)
  46. return python::detail::none();
  47. else
  48. return this->execute(*ptr, mpl::false_());
  49. }
  50. template <class U>
  51. inline PyObject* execute(U const& x, mpl::false_) const
  52. {
  53. U* const p = &const_cast<U&>(x);
  54. if (is_polymorphic<U>::value)
  55. {
  56. if (PyObject* o = detail::wrapper_base_::owner(p))
  57. return incref(o);
  58. }
  59. return MakeHolder::execute(p);
  60. }
  61. };
  62. //
  63. // implementations
  64. //
  65. namespace detail
  66. {
  67. struct make_owning_holder
  68. {
  69. template <class T>
  70. static PyObject* execute(T* p)
  71. {
  72. // can't use auto_ptr with Intel 5 and VC6 Dinkum library
  73. // for some reason. We get link errors against the auto_ptr
  74. // copy constructor.
  75. # if defined(__ICL) && __ICL < 600
  76. typedef boost::shared_ptr<T> smart_pointer;
  77. # else
  78. typedef std::auto_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