to_python_value.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright David Abrahams 2002.
  2. // Copyright Stefan Seefeld 2016.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef boost_python_to_python_value_hpp_
  7. #define boost_python_to_python_value_hpp_
  8. #include <boost/python/detail/prefix.hpp>
  9. #include <boost/python/refcount.hpp>
  10. #include <boost/python/tag.hpp>
  11. #include <boost/python/handle.hpp>
  12. #include <boost/python/converter/registry.hpp>
  13. #include <boost/python/converter/registered.hpp>
  14. #include <boost/python/converter/builtin_converters.hpp>
  15. #include <boost/python/converter/object_manager.hpp>
  16. #include <boost/python/converter/shared_ptr_to_python.hpp>
  17. #include <boost/python/detail/type_traits.hpp>
  18. #include <boost/python/detail/value_is_shared_ptr.hpp>
  19. #include <boost/python/detail/value_arg.hpp>
  20. #include <boost/mpl/if.hpp>
  21. #include <boost/mpl/or.hpp>
  22. namespace boost { namespace python {
  23. namespace detail
  24. {
  25. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  26. template <bool is_const_ref>
  27. struct object_manager_get_pytype
  28. {
  29. template <class U>
  30. static PyTypeObject const* get( U& (*)() =0)
  31. {
  32. return converter::object_manager_traits<U>::get_pytype();
  33. }
  34. };
  35. template <>
  36. struct object_manager_get_pytype<true>
  37. {
  38. template <class U>
  39. static PyTypeObject const* get( U const& (*)() =0)
  40. {
  41. return converter::object_manager_traits<U>::get_pytype();
  42. }
  43. };
  44. #endif
  45. template <class T>
  46. struct object_manager_to_python_value
  47. {
  48. typedef typename value_arg<T>::type argument_type;
  49. PyObject* operator()(argument_type) const;
  50. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  51. typedef boost::mpl::bool_<is_handle<T>::value> is_t_handle;
  52. typedef boost::detail::indirect_traits::is_reference_to_const<T> is_t_const;
  53. PyTypeObject const* get_pytype() const {
  54. return get_pytype_aux((is_t_handle*)0);
  55. }
  56. inline static PyTypeObject const* get_pytype_aux(mpl::true_*) {return converter::object_manager_traits<T>::get_pytype();}
  57. inline static PyTypeObject const* get_pytype_aux(mpl::false_* )
  58. {
  59. return object_manager_get_pytype<is_t_const::value>::get((T(*)())0);
  60. }
  61. #endif
  62. // This information helps make_getter() decide whether to try to
  63. // return an internal reference or not. I don't like it much,
  64. // but it will have to serve for now.
  65. BOOST_STATIC_CONSTANT(bool, uses_registry = false);
  66. };
  67. template <class T>
  68. struct registry_to_python_value
  69. {
  70. typedef typename value_arg<T>::type argument_type;
  71. PyObject* operator()(argument_type) const;
  72. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  73. PyTypeObject const* get_pytype() const {return converter::registered<T>::converters.to_python_target_type();}
  74. #endif
  75. // This information helps make_getter() decide whether to try to
  76. // return an internal reference or not. I don't like it much,
  77. // but it will have to serve for now.
  78. BOOST_STATIC_CONSTANT(bool, uses_registry = true);
  79. };
  80. template <class T>
  81. struct shared_ptr_to_python_value
  82. {
  83. typedef typename value_arg<T>::type argument_type;
  84. PyObject* operator()(argument_type) const;
  85. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  86. PyTypeObject const* get_pytype() const {return get_pytype((boost::type<argument_type>*)0);}
  87. #endif
  88. // This information helps make_getter() decide whether to try to
  89. // return an internal reference or not. I don't like it much,
  90. // but it will have to serve for now.
  91. BOOST_STATIC_CONSTANT(bool, uses_registry = false);
  92. private:
  93. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  94. template <class U>
  95. PyTypeObject const* get_pytype(boost::type<shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
  96. template <class U>
  97. PyTypeObject const* get_pytype(boost::type<const shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
  98. # if !defined(BOOST_NO_CXX11_SMART_PTR)
  99. template <class U>
  100. PyTypeObject const* get_pytype(boost::type<std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
  101. template <class U>
  102. PyTypeObject const* get_pytype(boost::type<const std::shared_ptr<U> &> *) const {return converter::registered<U>::converters.to_python_target_type();}
  103. # endif
  104. #endif
  105. };
  106. }
  107. template <class T>
  108. struct to_python_value
  109. : mpl::if_<
  110. detail::value_is_shared_ptr<T>
  111. , detail::shared_ptr_to_python_value<T>
  112. , typename mpl::if_<
  113. mpl::or_<
  114. converter::is_object_manager<T>
  115. , converter::is_reference_to_object_manager<T>
  116. >
  117. , detail::object_manager_to_python_value<T>
  118. , detail::registry_to_python_value<T>
  119. >::type
  120. >::type
  121. {
  122. };
  123. //
  124. // implementation
  125. //
  126. namespace detail
  127. {
  128. template <class T>
  129. inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
  130. {
  131. return converter::registered<argument_type>::converters.to_python(&x);
  132. }
  133. template <class T>
  134. inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
  135. {
  136. return python::upcast<PyObject>(
  137. python::xincref(
  138. get_managed_object(x, tag))
  139. );
  140. }
  141. template <class T>
  142. inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const
  143. {
  144. return converter::shared_ptr_to_python(x);
  145. }
  146. }
  147. }} // namespace boost::python
  148. #endif