|
1 | 1 | #if !defined(BOOST_PP_IS_ITERATING) |
2 | 2 |
|
3 | | -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and |
4 | | -// distribute this software is granted provided this copyright notice appears |
5 | | -// in all copies. This software is provided "as is" without express or implied |
6 | | -// warranty, and with no claim as to its suitability for any purpose. |
7 | | -// |
8 | | -// The author gratefully acknowleges the support of Dragon Systems, Inc., in |
9 | | -// producing this work. |
10 | | -// |
11 | | -// This file generated for 10-argument member functions and 11-argument free |
12 | | -// functions by gen_caller.python |
| 3 | +// Copyright David Abrahams 2002. Permission to copy, use, |
| 4 | +// modify, sell and distribute this software is granted provided this |
| 5 | +// copyright notice appears in all copies. This software is provided |
| 6 | +// "as is" without express or implied warranty, and with no claim as |
| 7 | +// to its suitability for any purpose. |
13 | 8 |
|
14 | | -# ifndef CALLER_DWA20011214_HPP |
15 | | -# define CALLER_DWA20011214_HPP |
| 9 | +# ifndef CALLER_DWA20021121_HPP |
| 10 | +# define CALLER_DWA20021121_HPP |
16 | 11 |
|
17 | | -# include <boost/python/detail/wrap_python.hpp> |
18 | | -# include <boost/python/detail/returning.hpp> |
19 | | -# include <boost/python/detail/preprocessor.hpp> |
| 12 | +# include <boost/compressed_pair.hpp> |
20 | 13 |
|
21 | | -# include <boost/type_traits/composite_traits.hpp> |
22 | | -# include <boost/type_traits/same_traits.hpp> |
| 14 | +# include <boost/mpl/apply.hpp> |
| 15 | +# include <boost/mpl/if.hpp> |
| 16 | +# include <boost/mpl/size.hpp> |
| 17 | +# include <boost/type_traits/is_same.hpp> |
23 | 18 |
|
24 | | -# include <boost/preprocessor/comma_if.hpp> |
| 19 | +# include <boost/python/detail/preprocessor.hpp> |
25 | 20 | # include <boost/preprocessor/iterate.hpp> |
26 | | -# include <boost/preprocessor/debug/line.hpp> |
| 21 | +# include <boost/preprocessor/iteration/local.hpp> |
27 | 22 | # include <boost/preprocessor/repetition/enum_trailing_params.hpp> |
28 | | - |
29 | | -namespace boost { namespace python |
| 23 | +# include <boost/preprocessor/repetition/repeat.hpp> |
| 24 | +# include <boost/preprocessor/cat.hpp> |
| 25 | +# include <boost/preprocessor/dec.hpp> |
| 26 | +# include <boost/preprocessor/if.hpp> |
| 27 | + |
| 28 | +# include <boost/python/detail/invoke.hpp> |
| 29 | + |
| 30 | +namespace boost { namespace python { namespace detail { |
| 31 | + |
| 32 | +// This "result converter" is really just used as |
| 33 | +// a dispatch tag to invoke(...), selecting the appropriate |
| 34 | +// implementation |
| 35 | +typedef int void_result_to_python; |
| 36 | + |
| 37 | +// A metafunction taking an iterator FunctionIter to a metafunction |
| 38 | +// class and an iterator ArgIter to an argument, which applies the |
| 39 | +// result of dereferencing FunctionIter to the result of dereferencing |
| 40 | +// ArgIter |
| 41 | +template <class FunctionIter, class ArgIter> |
| 42 | +struct apply_iter1 |
| 43 | + : mpl::apply1<typename FunctionIter::type, typename ArgIter::type> {}; |
| 44 | + |
| 45 | +// Given a model of CallPolicies and a C++ result type, this |
| 46 | +// metafunction selects the appropriate converter to use for |
| 47 | +// converting the result to python. |
| 48 | +template <class Policies, class Result> |
| 49 | +struct select_result_converter |
| 50 | + : mpl::if_< |
| 51 | + is_same<Result,void> |
| 52 | + , void_result_to_python |
| 53 | + , typename mpl::apply1<typename Policies::result_converter,Result>::type* |
| 54 | + > |
30 | 55 | { |
31 | | - template <class T> struct to_python; |
32 | | -}} |
| 56 | +}; |
33 | 57 |
|
34 | | -namespace boost { namespace python { namespace detail { |
35 | 58 |
|
36 | | -struct caller |
37 | | -{ |
38 | | - typedef PyObject* result_type; |
| 59 | +template <unsigned> struct caller_gen; |
39 | 60 |
|
40 | | - // function pointers |
41 | | -# define BOOST_PP_ITERATION_PARAMS_1 \ |
42 | | - (4, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/caller.hpp>, BOOST_PYTHON_FUNCTION_POINTER)) |
43 | | -# include BOOST_PP_ITERATE() |
| 61 | +# define BOOST_PYTHON_NEXT(init,name,n) \ |
| 62 | + typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n; |
44 | 63 |
|
45 | | - // pointers-to-members |
46 | | -# define BOOST_PP_ITERATION_PARAMS_1 \ |
47 | | - (4, (0, 3, <boost/python/detail/caller.hpp>, BOOST_PYTHON_POINTER_TO_MEMBER)) |
| 64 | +# define BOOST_PYTHON_ARG_CONVERTER(n) \ |
| 65 | + BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \ |
| 66 | + BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \ |
| 67 | + typedef typename apply_iter1<conv_iter##n,arg_iter##n>::type c_t##n; \ |
| 68 | + c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \ |
| 69 | + if (!c##n.convertible()) \ |
| 70 | + return 0; |
| 71 | + |
| 72 | +# define BOOST_PP_ITERATION_PARAMS_1 \ |
| 73 | + (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>)) |
48 | 74 | # include BOOST_PP_ITERATE() |
49 | 75 |
|
| 76 | +# undef BOOST_PYTHON_ARG_CONVERTER |
| 77 | +# undef BOOST_PYTHON_NEXT |
| 78 | + |
| 79 | +// A metafunction returning the base class used for caller<class F, |
| 80 | +// class ConverterGenerators, class CallPolicies, class Sig>. |
| 81 | +template <class F, class ConverterGenerators, class CallPolicies, class Sig> |
| 82 | +struct caller_base_select |
| 83 | +{ |
| 84 | + enum { n_arguments = mpl::size<Sig>::value - 1 }; |
| 85 | + typedef typename caller_gen<n_arguments>::template impl<F,ConverterGenerators,CallPolicies,Sig> type; |
50 | 86 | }; |
51 | 87 |
|
52 | | -}}} // namespace boost::python::detail |
| 88 | +// A function object type which wraps C++ objects as Python callable |
| 89 | +// objects. |
| 90 | +// |
| 91 | +// Template Arguments: |
| 92 | +// |
| 93 | +// F - |
| 94 | +// the C++ `function object' that will be called. Might |
| 95 | +// actually be any data for which an appropriate invoke_tag() can |
| 96 | +// be generated. invoke(...) takes care of the actual invocation syntax. |
| 97 | +// |
| 98 | +// ConverterGenerators - |
| 99 | +// An MPL iterator type over a sequence of metafunction classes |
| 100 | +// that can be applied to element 1...N of Sig to produce |
| 101 | +// argument from_python converters for the arguments |
| 102 | +// |
| 103 | +// CallPolicies - |
| 104 | +// The precall, postcall, and what kind of resultconverter to |
| 105 | +// generate for mpl::front<Sig>::type |
| 106 | +// |
| 107 | +// Sig - |
| 108 | +// The `intended signature' of the function. An MPL sequence |
| 109 | +// beginning with a result type and continuing with a list of |
| 110 | +// argument types. |
| 111 | +template <class F, class ConverterGenerators, class CallPolicies, class Sig> |
| 112 | +struct caller |
| 113 | + : caller_base_select<F,ConverterGenerators,CallPolicies,Sig>::type |
| 114 | +{ |
| 115 | + typedef typename caller_base_select< |
| 116 | + F,ConverterGenerators,CallPolicies,Sig |
| 117 | + >::type base; |
53 | 118 |
|
54 | | -# endif // CALLER_DWA20011214_HPP |
| 119 | + typedef PyObject* result_type; |
| 120 | + |
| 121 | + caller(F f, CallPolicies p) : base(f,p) {} |
| 122 | +}; |
55 | 123 |
|
56 | | -/* ---------- function pointers --------- */ |
57 | | -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER |
58 | | -# line BOOST_PP_LINE(__LINE__, detail/caller.hpp(function pointers)) |
59 | 124 |
|
60 | | -# define N BOOST_PP_ITERATION() |
| 125 | +}}} // namespace boost::python::detail |
61 | 126 |
|
62 | | -template < |
63 | | - class P, class R |
64 | | - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) |
65 | | - > |
66 | | -PyObject* operator()( |
67 | | - R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) |
68 | | - , PyObject* args |
69 | | - , PyObject* keywords |
70 | | - , P const& policies) const |
71 | | -{ |
72 | | - return returning<R>::call(pf, args, keywords, &policies); |
73 | | -} |
| 127 | +# endif // CALLER_DWA20021121_HPP |
74 | 128 |
|
75 | | -# undef N |
| 129 | +#else |
76 | 130 |
|
77 | | -/* ---------- pointers-to-members ---------- */ |
78 | | -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER |
79 | | -// outer over cv-qualifiers |
| 131 | +# define N BOOST_PP_ITERATION() |
80 | 132 |
|
81 | | -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, <boost/python/detail/caller.hpp>)) |
82 | | -# include BOOST_PP_ITERATE() |
| 133 | +template <> |
| 134 | +struct caller_gen<N> |
| 135 | +{ |
| 136 | + template <class F, class ConverterGenerators, class Policies, class Sig> |
| 137 | + struct impl |
| 138 | + { |
| 139 | + impl(F f, Policies p) : m_data(f,p) {} |
| 140 | + |
| 141 | + PyObject* operator()(PyObject* args_, PyObject*) // eliminate |
| 142 | + // this |
| 143 | + // trailing |
| 144 | + // keyword dict |
| 145 | + { |
| 146 | + typedef typename mpl::begin<Sig>::type first; |
| 147 | + typedef typename first::type result_t; |
| 148 | + typedef typename select_result_converter<Policies, result_t>::type result_converter; |
| 149 | +# if N |
| 150 | +# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) |
| 151 | +# define BOOST_PP_LOCAL_LIMITS (0, N-1) |
| 152 | +# include BOOST_PP_LOCAL_ITERATE() |
| 153 | +# endif |
| 154 | + // all converters have been checked. Now we can do the |
| 155 | + // precall part of the policy |
| 156 | + if (!m_data.second().precall(args_)) |
| 157 | + return 0; |
| 158 | + |
| 159 | + typedef typename detail::invoke_tag<F>::type tag; |
| 160 | + |
| 161 | + PyObject* result = detail::invoke( |
| 162 | + tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c)); |
| 163 | + |
| 164 | + return m_data.second().postcall(args_, result); |
| 165 | + } |
| 166 | + private: |
| 167 | + compressed_pair<F,Policies> m_data; |
| 168 | + }; |
| 169 | +}; |
83 | 170 |
|
84 | | -#elif BOOST_PP_ITERATION_DEPTH() == 2 |
85 | | -// inner over arities |
86 | 171 |
|
87 | | -#define N BOOST_PP_ITERATION() |
88 | | -#define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) |
89 | 172 |
|
90 | | -template < |
91 | | - class P, class R, class T |
92 | | - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) |
93 | | - > |
94 | | -PyObject* operator()( |
95 | | - R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q |
96 | | - , PyObject* args, PyObject* keywords |
97 | | - , P const& policies |
98 | | - ) const |
99 | | -{ |
100 | | - return returning<R>::call(pmf, args, keywords, &policies); |
101 | | -} |
| 173 | +#endif // BOOST_PP_IS_ITERATING |
102 | 174 |
|
103 | | -#undef N |
104 | | -#undef Q |
105 | 175 |
|
106 | | -#endif |
|
0 commit comments