annotate DEPENDENCIES/generic/include/boost/python/detail/caller.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 #if !defined(BOOST_PP_IS_ITERATING)
Chris@16 2
Chris@16 3 // Copyright David Abrahams 2002.
Chris@16 4 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 5 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 # ifndef CALLER_DWA20021121_HPP
Chris@16 9 # define CALLER_DWA20021121_HPP
Chris@16 10
Chris@16 11 # include <boost/python/type_id.hpp>
Chris@16 12 # include <boost/python/handle.hpp>
Chris@16 13
Chris@16 14 # include <boost/detail/indirect_traits.hpp>
Chris@16 15
Chris@16 16 # include <boost/python/detail/invoke.hpp>
Chris@16 17 # include <boost/python/detail/signature.hpp>
Chris@16 18 # include <boost/python/detail/preprocessor.hpp>
Chris@16 19
Chris@16 20 # include <boost/python/arg_from_python.hpp>
Chris@16 21 # include <boost/python/converter/context_result_converter.hpp>
Chris@16 22 # include <boost/python/converter/builtin_converters.hpp>
Chris@16 23
Chris@16 24 # include <boost/preprocessor/iterate.hpp>
Chris@16 25 # include <boost/preprocessor/cat.hpp>
Chris@16 26 # include <boost/preprocessor/dec.hpp>
Chris@16 27 # include <boost/preprocessor/if.hpp>
Chris@16 28 # include <boost/preprocessor/iteration/local.hpp>
Chris@16 29 # include <boost/preprocessor/repetition/enum_trailing_params.hpp>
Chris@16 30 # include <boost/preprocessor/repetition/repeat.hpp>
Chris@16 31
Chris@16 32 # include <boost/compressed_pair.hpp>
Chris@16 33
Chris@16 34 # include <boost/type_traits/is_same.hpp>
Chris@16 35 # include <boost/type_traits/is_convertible.hpp>
Chris@16 36
Chris@16 37 # include <boost/mpl/apply.hpp>
Chris@16 38 # include <boost/mpl/eval_if.hpp>
Chris@16 39 # include <boost/mpl/identity.hpp>
Chris@16 40 # include <boost/mpl/size.hpp>
Chris@16 41 # include <boost/mpl/at.hpp>
Chris@16 42 # include <boost/mpl/int.hpp>
Chris@16 43 # include <boost/mpl/next.hpp>
Chris@16 44
Chris@16 45 namespace boost { namespace python { namespace detail {
Chris@16 46
Chris@16 47 template <int N>
Chris@16 48 inline PyObject* get(mpl::int_<N>, PyObject* const& args_)
Chris@16 49 {
Chris@16 50 return PyTuple_GET_ITEM(args_,N);
Chris@16 51 }
Chris@16 52
Chris@16 53 inline unsigned arity(PyObject* const& args_)
Chris@16 54 {
Chris@16 55 return PyTuple_GET_SIZE(args_);
Chris@16 56 }
Chris@16 57
Chris@16 58 // This "result converter" is really just used as
Chris@16 59 // a dispatch tag to invoke(...), selecting the appropriate
Chris@16 60 // implementation
Chris@16 61 typedef int void_result_to_python;
Chris@16 62
Chris@16 63 // Given a model of CallPolicies and a C++ result type, this
Chris@16 64 // metafunction selects the appropriate converter to use for
Chris@16 65 // converting the result to python.
Chris@16 66 template <class Policies, class Result>
Chris@16 67 struct select_result_converter
Chris@16 68 : mpl::eval_if<
Chris@16 69 is_same<Result,void>
Chris@16 70 , mpl::identity<void_result_to_python>
Chris@16 71 , mpl::apply1<typename Policies::result_converter,Result>
Chris@16 72 >
Chris@16 73 {
Chris@16 74 };
Chris@16 75
Chris@16 76 template <class ArgPackage, class ResultConverter>
Chris@16 77 inline ResultConverter create_result_converter(
Chris@16 78 ArgPackage const& args_
Chris@16 79 , ResultConverter*
Chris@16 80 , converter::context_result_converter*
Chris@16 81 )
Chris@16 82 {
Chris@16 83 return ResultConverter(args_);
Chris@16 84 }
Chris@16 85
Chris@16 86 template <class ArgPackage, class ResultConverter>
Chris@16 87 inline ResultConverter create_result_converter(
Chris@16 88 ArgPackage const&
Chris@16 89 , ResultConverter*
Chris@16 90 , ...
Chris@16 91 )
Chris@16 92 {
Chris@16 93 return ResultConverter();
Chris@16 94 }
Chris@16 95
Chris@16 96 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
Chris@16 97 template <class ResultConverter>
Chris@16 98 struct converter_target_type
Chris@16 99 {
Chris@16 100 static PyTypeObject const *get_pytype()
Chris@16 101 {
Chris@16 102 return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
Chris@16 103 }
Chris@16 104 };
Chris@16 105
Chris@16 106 template < >
Chris@16 107 struct converter_target_type <void_result_to_python >
Chris@16 108 {
Chris@16 109 static PyTypeObject const *get_pytype()
Chris@16 110 {
Chris@16 111 return 0;
Chris@16 112 }
Chris@16 113 };
Chris@16 114 #endif
Chris@16 115
Chris@16 116
Chris@16 117 template <unsigned> struct caller_arity;
Chris@16 118
Chris@16 119 template <class F, class CallPolicies, class Sig>
Chris@16 120 struct caller;
Chris@16 121
Chris@16 122 # define BOOST_PYTHON_NEXT(init,name,n) \
Chris@16 123 typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n;
Chris@16 124
Chris@16 125 # define BOOST_PYTHON_ARG_CONVERTER(n) \
Chris@16 126 BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \
Chris@16 127 typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
Chris@16 128 c_t##n c##n(get(mpl::int_<n>(), inner_args)); \
Chris@16 129 if (!c##n.convertible()) \
Chris@16 130 return 0;
Chris@16 131
Chris@16 132 # define BOOST_PP_ITERATION_PARAMS_1 \
Chris@16 133 (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>))
Chris@16 134 # include BOOST_PP_ITERATE()
Chris@16 135
Chris@16 136 # undef BOOST_PYTHON_ARG_CONVERTER
Chris@16 137 # undef BOOST_PYTHON_NEXT
Chris@16 138
Chris@16 139 // A metafunction returning the base class used for caller<class F,
Chris@16 140 // class ConverterGenerators, class CallPolicies, class Sig>.
Chris@16 141 template <class F, class CallPolicies, class Sig>
Chris@16 142 struct caller_base_select
Chris@16 143 {
Chris@16 144 enum { arity = mpl::size<Sig>::value - 1 };
Chris@16 145 typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type;
Chris@16 146 };
Chris@16 147
Chris@16 148 // A function object type which wraps C++ objects as Python callable
Chris@16 149 // objects.
Chris@16 150 //
Chris@16 151 // Template Arguments:
Chris@16 152 //
Chris@16 153 // F -
Chris@16 154 // the C++ `function object' that will be called. Might
Chris@16 155 // actually be any data for which an appropriate invoke_tag() can
Chris@16 156 // be generated. invoke(...) takes care of the actual invocation syntax.
Chris@16 157 //
Chris@16 158 // CallPolicies -
Chris@16 159 // The precall, postcall, and what kind of resultconverter to
Chris@16 160 // generate for mpl::front<Sig>::type
Chris@16 161 //
Chris@16 162 // Sig -
Chris@16 163 // The `intended signature' of the function. An MPL sequence
Chris@16 164 // beginning with a result type and continuing with a list of
Chris@16 165 // argument types.
Chris@16 166 template <class F, class CallPolicies, class Sig>
Chris@16 167 struct caller
Chris@16 168 : caller_base_select<F,CallPolicies,Sig>::type
Chris@16 169 {
Chris@16 170 typedef typename caller_base_select<
Chris@16 171 F,CallPolicies,Sig
Chris@16 172 >::type base;
Chris@16 173
Chris@16 174 typedef PyObject* result_type;
Chris@16 175
Chris@16 176 caller(F f, CallPolicies p) : base(f,p) {}
Chris@16 177
Chris@16 178 };
Chris@16 179
Chris@16 180 }}} // namespace boost::python::detail
Chris@16 181
Chris@16 182 # endif // CALLER_DWA20021121_HPP
Chris@16 183
Chris@16 184 #else
Chris@16 185
Chris@16 186 # define N BOOST_PP_ITERATION()
Chris@16 187
Chris@16 188 template <>
Chris@16 189 struct caller_arity<N>
Chris@16 190 {
Chris@16 191 template <class F, class Policies, class Sig>
Chris@16 192 struct impl
Chris@16 193 {
Chris@16 194 impl(F f, Policies p) : m_data(f,p) {}
Chris@16 195
Chris@16 196 PyObject* operator()(PyObject* args_, PyObject*) // eliminate
Chris@16 197 // this
Chris@16 198 // trailing
Chris@16 199 // keyword dict
Chris@16 200 {
Chris@16 201 typedef typename mpl::begin<Sig>::type first;
Chris@16 202 typedef typename first::type result_t;
Chris@16 203 typedef typename select_result_converter<Policies, result_t>::type result_converter;
Chris@16 204 typedef typename Policies::argument_package argument_package;
Chris@16 205
Chris@16 206 argument_package inner_args(args_);
Chris@16 207
Chris@16 208 # if N
Chris@16 209 # define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
Chris@16 210 # define BOOST_PP_LOCAL_LIMITS (0, N-1)
Chris@16 211 # include BOOST_PP_LOCAL_ITERATE()
Chris@16 212 # endif
Chris@16 213 // all converters have been checked. Now we can do the
Chris@16 214 // precall part of the policy
Chris@16 215 if (!m_data.second().precall(inner_args))
Chris@16 216 return 0;
Chris@16 217
Chris@16 218 PyObject* result = detail::invoke(
Chris@16 219 detail::invoke_tag<result_t,F>()
Chris@16 220 , create_result_converter(args_, (result_converter*)0, (result_converter*)0)
Chris@16 221 , m_data.first()
Chris@16 222 BOOST_PP_ENUM_TRAILING_PARAMS(N, c)
Chris@16 223 );
Chris@16 224
Chris@16 225 return m_data.second().postcall(inner_args, result);
Chris@16 226 }
Chris@16 227
Chris@16 228 static unsigned min_arity() { return N; }
Chris@16 229
Chris@16 230 static py_func_sig_info signature()
Chris@16 231 {
Chris@16 232 const signature_element * sig = detail::signature<Sig>::elements();
Chris@16 233 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
Chris@16 234
Chris@16 235 typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
Chris@16 236 typedef typename select_result_converter<Policies, rtype>::type result_converter;
Chris@16 237
Chris@16 238 static const signature_element ret = {
Chris@16 239 (boost::is_void<rtype>::value ? "void" : type_id<rtype>().name())
Chris@16 240 , &detail::converter_target_type<result_converter>::get_pytype
Chris@16 241 , boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
Chris@16 242 };
Chris@16 243 py_func_sig_info res = {sig, &ret };
Chris@16 244 #else
Chris@16 245 py_func_sig_info res = {sig, sig };
Chris@16 246 #endif
Chris@16 247
Chris@16 248 return res;
Chris@16 249 }
Chris@16 250 private:
Chris@16 251 compressed_pair<F,Policies> m_data;
Chris@16 252 };
Chris@16 253 };
Chris@16 254
Chris@16 255
Chris@16 256
Chris@16 257 #endif // BOOST_PP_IS_ITERATING
Chris@16 258
Chris@16 259