obj_mgr_arg_from_python.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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 OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
  6. # define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/detail/referent_storage.hpp>
  9. # include <boost/python/detail/destroy.hpp>
  10. # include <boost/python/detail/construct.hpp>
  11. # include <boost/python/converter/object_manager.hpp>
  12. # include <boost/python/detail/raw_pyobject.hpp>
  13. # include <boost/python/tag.hpp>
  14. //
  15. // arg_from_python converters for Python type wrappers, to be used as
  16. // base classes for specializations.
  17. //
  18. namespace boost { namespace python { namespace converter {
  19. template <class T>
  20. struct object_manager_value_arg_from_python
  21. {
  22. typedef T result_type;
  23. object_manager_value_arg_from_python(PyObject*);
  24. bool convertible() const;
  25. T operator()() const;
  26. private:
  27. PyObject* m_source;
  28. };
  29. // Used for converting reference-to-object-manager arguments from
  30. // python. The process used here is a little bit odd. Upon
  31. // construction, we build the object manager object in the m_result
  32. // object, *forcing* it to accept the source Python object by casting
  33. // its pointer to detail::borrowed_reference. This is supposed to
  34. // bypass any type checking of the source object. The convertible
  35. // check then extracts the owned object and checks it. If the check
  36. // fails, nothing else in the program ever gets to touch this strange
  37. // "forced" object.
  38. template <class Ref>
  39. struct object_manager_ref_arg_from_python
  40. {
  41. typedef Ref result_type;
  42. object_manager_ref_arg_from_python(PyObject*);
  43. bool convertible() const;
  44. Ref operator()() const;
  45. ~object_manager_ref_arg_from_python();
  46. private:
  47. typename python::detail::referent_storage<Ref>::type m_result;
  48. };
  49. //
  50. // implementations
  51. //
  52. template <class T>
  53. inline object_manager_value_arg_from_python<T>::object_manager_value_arg_from_python(PyObject* x)
  54. : m_source(x)
  55. {
  56. }
  57. template <class T>
  58. inline bool object_manager_value_arg_from_python<T>::convertible() const
  59. {
  60. return object_manager_traits<T>::check(m_source);
  61. }
  62. template <class T>
  63. inline T object_manager_value_arg_from_python<T>::operator()() const
  64. {
  65. return T(python::detail::borrowed_reference(m_source));
  66. }
  67. template <class Ref>
  68. inline object_manager_ref_arg_from_python<Ref>::object_manager_ref_arg_from_python(PyObject* x)
  69. {
  70. # if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
  71. // needed for warning suppression
  72. python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x);
  73. python::detail::construct_referent<Ref>(m_result.bytes, x_);
  74. # else
  75. python::detail::construct_referent<Ref>(m_result.bytes, (python::detail::borrowed_reference)x);
  76. # endif
  77. }
  78. template <class Ref>
  79. inline object_manager_ref_arg_from_python<Ref>::~object_manager_ref_arg_from_python()
  80. {
  81. python::detail::destroy_referent<Ref>(this->m_result.bytes);
  82. }
  83. namespace detail
  84. {
  85. template <class T>
  86. inline bool object_manager_ref_check(T const& x)
  87. {
  88. return object_manager_traits<T>::check(get_managed_object(x, tag));
  89. }
  90. }
  91. template <class Ref>
  92. inline bool object_manager_ref_arg_from_python<Ref>::convertible() const
  93. {
  94. return detail::object_manager_ref_check(
  95. python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0));
  96. }
  97. template <class Ref>
  98. inline Ref object_manager_ref_arg_from_python<Ref>::operator()() const
  99. {
  100. return python::detail::void_ptr_to_reference(
  101. this->m_result.bytes, (Ref(*)())0);
  102. }
  103. }}} // namespace boost::python::converter
  104. #endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP