return_arg.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright David Abrahams and Nikolay Mladenov 2003.
  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_ARG_DWA2003719_HPP
  6. # define RETURN_ARG_DWA2003719_HPP
  7. # include <boost/python/default_call_policies.hpp>
  8. # include <boost/python/detail/none.hpp>
  9. # include <boost/python/detail/value_arg.hpp>
  10. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  11. # include <boost/python/converter/pytype_function.hpp>
  12. #endif
  13. # include <boost/python/detail/type_traits.hpp>
  14. # include <boost/mpl/int.hpp>
  15. # include <boost/mpl/at.hpp>
  16. # include <boost/static_assert.hpp>
  17. # include <boost/python/refcount.hpp>
  18. # include <cstddef>
  19. namespace boost { namespace python {
  20. namespace detail
  21. {
  22. template <std::size_t>
  23. struct return_arg_pos_argument_must_be_positive
  24. # if defined(__GNUC__) || defined(__EDG__)
  25. {}
  26. # endif
  27. ;
  28. struct return_none
  29. {
  30. template <class T> struct apply
  31. {
  32. struct type
  33. {
  34. static bool convertible()
  35. {
  36. return true;
  37. }
  38. PyObject *operator()( typename value_arg<T>::type ) const
  39. {
  40. return none();
  41. }
  42. #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
  43. PyTypeObject const *get_pytype() const { return converter::expected_pytype_for_arg<T>::get_pytype() ; }
  44. #endif
  45. };
  46. };
  47. };
  48. }
  49. template <
  50. std::size_t arg_pos=1
  51. , class Base = default_call_policies
  52. >
  53. struct return_arg : Base
  54. {
  55. private:
  56. BOOST_STATIC_CONSTANT(bool, legal = arg_pos > 0);
  57. public:
  58. typedef typename mpl::if_c<
  59. legal
  60. , detail::return_none
  61. , detail::return_arg_pos_argument_must_be_positive<arg_pos>
  62. // we could default to the base result_converter in case or
  63. // arg_pos==0 since return arg 0 means return result, but I
  64. // think it is better to issue an error instead, cause it can
  65. // lead to confusions
  66. >::type result_converter;
  67. template <class ArgumentPackage>
  68. static PyObject* postcall(ArgumentPackage const& args, PyObject* result)
  69. {
  70. // In case of arg_pos == 0 we could simply return Base::postcall,
  71. // but this is redundant
  72. BOOST_STATIC_ASSERT(arg_pos > 0);
  73. result = Base::postcall(args,result);
  74. if (!result)
  75. return 0;
  76. Py_DECREF(result);
  77. return incref( detail::get(mpl::int_<arg_pos-1>(),args) );
  78. }
  79. template <class Sig>
  80. struct extract_return_type : mpl::at_c<Sig, arg_pos>
  81. {
  82. };
  83. };
  84. template <
  85. class Base = default_call_policies
  86. >
  87. struct return_self
  88. : return_arg<1,Base>
  89. {};
  90. }} // namespace boost::python
  91. #endif // RETURN_ARG_DWA2003719_HPP