]>
Commit | Line | Data |
---|---|---|
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 extract_return_type : 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 |