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