return_from_python.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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 RETURN_FROM_PYTHON_DWA200265_HPP
  6. # define RETURN_FROM_PYTHON_DWA200265_HPP
  7. # include <boost/python/converter/from_python.hpp>
  8. # include <boost/python/converter/rvalue_from_python_data.hpp>
  9. # include <boost/python/converter/registered.hpp>
  10. # include <boost/python/converter/registered_pointee.hpp>
  11. # include <boost/python/converter/object_manager.hpp>
  12. # include <boost/python/detail/void_ptr.hpp>
  13. # include <boost/python/detail/void_return.hpp>
  14. # include <boost/python/errors.hpp>
  15. # include <boost/python/handle.hpp>
  16. # include <boost/python/detail/type_traits.hpp>
  17. # include <boost/mpl/and.hpp>
  18. # include <boost/mpl/bool.hpp>
  19. namespace boost { namespace python { namespace converter {
  20. template <class T> struct is_object_manager;
  21. namespace detail
  22. {
  23. template <class T>
  24. struct return_pointer_from_python
  25. {
  26. typedef T result_type;
  27. T operator()(PyObject*) const;
  28. };
  29. template <class T>
  30. struct return_reference_from_python
  31. {
  32. typedef T result_type;
  33. T operator()(PyObject*) const;
  34. };
  35. template <class T>
  36. struct return_rvalue_from_python
  37. {
  38. typedef T result_type;
  39. return_rvalue_from_python();
  40. result_type operator()(PyObject*);
  41. private:
  42. rvalue_from_python_data<T> m_data;
  43. };
  44. template <class T>
  45. struct return_object_manager_from_python
  46. {
  47. typedef T result_type;
  48. result_type operator()(PyObject*) const;
  49. };
  50. template <class T>
  51. struct select_return_from_python
  52. {
  53. BOOST_STATIC_CONSTANT(
  54. bool, obj_mgr = is_object_manager<T>::value);
  55. BOOST_STATIC_CONSTANT(
  56. bool, ptr = is_pointer<T>::value);
  57. BOOST_STATIC_CONSTANT(
  58. bool, ref = is_reference<T>::value);
  59. typedef typename mpl::if_c<
  60. obj_mgr
  61. , return_object_manager_from_python<T>
  62. , typename mpl::if_c<
  63. ptr
  64. , return_pointer_from_python<T>
  65. , typename mpl::if_c<
  66. ref
  67. , return_reference_from_python<T>
  68. , return_rvalue_from_python<T>
  69. >::type
  70. >::type
  71. >::type type;
  72. };
  73. }
  74. template <class T>
  75. struct return_from_python
  76. : detail::select_return_from_python<T>::type
  77. {
  78. };
  79. // Specialization as a convenience for call and call_method
  80. template <>
  81. struct return_from_python<void>
  82. {
  83. typedef python::detail::returnable<void>::type result_type;
  84. result_type operator()(PyObject* x) const
  85. {
  86. (void_result_from_python)(x);
  87. # ifdef BOOST_NO_VOID_RETURNS
  88. return result_type();
  89. # endif
  90. }
  91. };
  92. //
  93. // Implementations
  94. //
  95. namespace detail
  96. {
  97. template <class T>
  98. inline return_rvalue_from_python<T>::return_rvalue_from_python()
  99. : m_data(
  100. const_cast<registration*>(&registered<T>::converters)
  101. )
  102. {
  103. }
  104. template <class T>
  105. inline typename return_rvalue_from_python<T>::result_type
  106. return_rvalue_from_python<T>::operator()(PyObject* obj)
  107. {
  108. // Take possession of the source object here. If the result is in
  109. // fact going to be a copy of an lvalue embedded in the object,
  110. // and we take possession inside rvalue_result_from_python, it
  111. // will be destroyed too early.
  112. handle<> holder(obj);
  113. return *(T*)
  114. (rvalue_result_from_python)(obj, m_data.stage1);
  115. }
  116. template <class T>
  117. inline T return_reference_from_python<T>::operator()(PyObject* obj) const
  118. {
  119. return python::detail::void_ptr_to_reference(
  120. (reference_result_from_python)(obj, registered<T>::converters)
  121. , (T(*)())0);
  122. }
  123. template <class T>
  124. inline T return_pointer_from_python<T>::operator()(PyObject* obj) const
  125. {
  126. return T(
  127. (pointer_result_from_python)(obj, registered_pointee<T>::converters)
  128. );
  129. }
  130. template <class T>
  131. inline T return_object_manager_from_python<T>::operator()(PyObject* obj) const
  132. {
  133. return T(
  134. object_manager_traits<T>::adopt(expect_non_null(obj))
  135. );
  136. }
  137. }
  138. }}} // namespace boost::python::converter
  139. #endif // RETURN_FROM_PYTHON_DWA200265_HPP