to_python_value.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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_VALUE_DWA200221_HPP
  6. # define TO_PYTHON_VALUE_DWA200221_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/refcount.hpp>
  9. # include <boost/python/tag.hpp>
  10. # include <boost/python/handle.hpp>
  11. # include <boost/python/converter/registry.hpp>
  12. # include <boost/python/converter/registered.hpp>
  13. # include <boost/python/converter/builtin_converters.hpp>
  14. # include <boost/python/converter/object_manager.hpp>
  15. # include <boost/python/converter/shared_ptr_to_python.hpp>
  16. # include <boost/python/detail/value_is_shared_ptr.hpp>
  17. # include <boost/python/detail/value_arg.hpp>
  18. # include <boost/type_traits/transform_traits.hpp>
  19. # include <boost/mpl/if.hpp>
  20. # include <boost/mpl/or.hpp>
  21. # include <boost/type_traits/is_const.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. #endif
  99. };
  100. }
  101. template <class T>
  102. struct to_python_value
  103. : mpl::if_<
  104. detail::value_is_shared_ptr<T>
  105. , detail::shared_ptr_to_python_value<T>
  106. , typename mpl::if_<
  107. mpl::or_<
  108. converter::is_object_manager<T>
  109. , converter::is_reference_to_object_manager<T>
  110. >
  111. , detail::object_manager_to_python_value<T>
  112. , detail::registry_to_python_value<T>
  113. >::type
  114. >::type
  115. {
  116. };
  117. //
  118. // implementation
  119. //
  120. namespace detail
  121. {
  122. template <class T>
  123. inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
  124. {
  125. return converter::registered<argument_type>::converters.to_python(&x);
  126. }
  127. template <class T>
  128. inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
  129. {
  130. return python::upcast<PyObject>(
  131. python::xincref(
  132. get_managed_object(x, tag))
  133. );
  134. }
  135. template <class T>
  136. inline PyObject* shared_ptr_to_python_value<T>::operator()(argument_type x) const
  137. {
  138. return converter::shared_ptr_to_python(x);
  139. }
  140. }
  141. }} // namespace boost::python
  142. #endif // TO_PYTHON_VALUE_DWA200221_HPP