File indexing completed on 2025-01-18 09:50:37
0001 #if !defined(BOOST_PP_IS_ITERATING)
0002
0003
0004
0005
0006
0007
0008 # ifndef CALLER_DWA20021121_HPP
0009 # define CALLER_DWA20021121_HPP
0010
0011 # include <boost/python/type_id.hpp>
0012 # include <boost/python/handle.hpp>
0013
0014 # include <boost/detail/indirect_traits.hpp>
0015
0016 # include <boost/python/detail/invoke.hpp>
0017 # include <boost/python/detail/signature.hpp>
0018 # include <boost/python/detail/preprocessor.hpp>
0019 # include <boost/python/detail/type_traits.hpp>
0020
0021 # include <boost/python/arg_from_python.hpp>
0022 # include <boost/python/converter/context_result_converter.hpp>
0023 # include <boost/python/converter/builtin_converters.hpp>
0024
0025 # include <boost/preprocessor/iterate.hpp>
0026 # include <boost/preprocessor/cat.hpp>
0027 # include <boost/preprocessor/dec.hpp>
0028 # include <boost/preprocessor/if.hpp>
0029 # include <boost/preprocessor/iteration/local.hpp>
0030 # include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0031 # include <boost/preprocessor/repetition/repeat.hpp>
0032
0033 # include <boost/compressed_pair.hpp>
0034
0035 # include <boost/mpl/apply.hpp>
0036 # include <boost/mpl/eval_if.hpp>
0037 # include <boost/mpl/identity.hpp>
0038 # include <boost/mpl/size.hpp>
0039 # include <boost/mpl/at.hpp>
0040 # include <boost/mpl/int.hpp>
0041 # include <boost/mpl/next.hpp>
0042
0043 namespace boost { namespace python { namespace detail {
0044
0045 template <int N>
0046 inline PyObject* get(mpl::int_<N>, PyObject* const& args_)
0047 {
0048 return PyTuple_GET_ITEM(args_,N);
0049 }
0050
0051 inline Py_ssize_t arity(PyObject* const& args_)
0052 {
0053 return PyTuple_GET_SIZE(args_);
0054 }
0055
0056
0057
0058
0059 typedef int void_result_to_python;
0060
0061
0062
0063
0064 template <class Policies, class Result>
0065 struct select_result_converter
0066 : mpl::eval_if<
0067 is_same<Result,void>
0068 , mpl::identity<void_result_to_python>
0069 , mpl::apply1<typename Policies::result_converter,Result>
0070 >
0071 {
0072 };
0073
0074 template <class ArgPackage, class ResultConverter>
0075 inline ResultConverter create_result_converter(
0076 ArgPackage const& args_
0077 , ResultConverter*
0078 , converter::context_result_converter*
0079 )
0080 {
0081 return ResultConverter(args_);
0082 }
0083
0084 template <class ArgPackage, class ResultConverter>
0085 inline ResultConverter create_result_converter(
0086 ArgPackage const&
0087 , ResultConverter*
0088 , ...
0089 )
0090 {
0091 return ResultConverter();
0092 }
0093
0094 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0095 template <class ResultConverter>
0096 struct converter_target_type
0097 {
0098 static PyTypeObject const *get_pytype()
0099 {
0100 return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype();
0101 }
0102 };
0103
0104 template < >
0105 struct converter_target_type <void_result_to_python >
0106 {
0107 static PyTypeObject const *get_pytype()
0108 {
0109 return 0;
0110 }
0111 };
0112
0113
0114
0115 template<class Policies, class Sig> const signature_element* get_ret()
0116 {
0117 typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype;
0118 typedef typename select_result_converter<Policies, rtype>::type result_converter;
0119
0120 static const signature_element ret = {
0121 (is_void<rtype>::value ? "void" : type_id<rtype>().name())
0122 , &detail::converter_target_type<result_converter>::get_pytype
0123 , boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value
0124 };
0125
0126 return &ret;
0127 }
0128
0129 #endif
0130
0131
0132 template <unsigned> struct caller_arity;
0133
0134 template <class F, class CallPolicies, class Sig>
0135 struct caller;
0136
0137 # define BOOST_PYTHON_NEXT(init,name,n) \
0138 typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n;
0139
0140 # define BOOST_PYTHON_ARG_CONVERTER(n) \
0141 BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \
0142 typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
0143 c_t##n c##n(get(mpl::int_<n>(), inner_args)); \
0144 if (!c##n.convertible()) \
0145 return 0;
0146
0147 # define BOOST_PP_ITERATION_PARAMS_1 \
0148 (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>))
0149 # include BOOST_PP_ITERATE()
0150
0151 # undef BOOST_PYTHON_ARG_CONVERTER
0152 # undef BOOST_PYTHON_NEXT
0153
0154
0155
0156 template <class F, class CallPolicies, class Sig>
0157 struct caller_base_select
0158 {
0159 enum { arity = mpl::size<Sig>::value - 1 };
0160 typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type;
0161 };
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 template <class F, class CallPolicies, class Sig>
0182 struct caller
0183 : caller_base_select<F,CallPolicies,Sig>::type
0184 {
0185 typedef typename caller_base_select<
0186 F,CallPolicies,Sig
0187 >::type base;
0188
0189 typedef PyObject* result_type;
0190
0191 caller(F f, CallPolicies p) : base(f,p) {}
0192
0193 };
0194
0195 }}}
0196
0197 # endif
0198
0199 #else
0200
0201 # define N BOOST_PP_ITERATION()
0202
0203 template <>
0204 struct caller_arity<N>
0205 {
0206 template <class F, class Policies, class Sig>
0207 struct impl
0208 {
0209 impl(F f, Policies p) : m_data(f,p) {}
0210
0211 PyObject* operator()(PyObject* args_, PyObject*)
0212
0213
0214
0215 {
0216 typedef typename mpl::begin<Sig>::type first;
0217 typedef typename first::type result_t;
0218 typedef typename select_result_converter<Policies, result_t>::type result_converter;
0219 typedef typename Policies::argument_package argument_package;
0220
0221 argument_package inner_args(args_);
0222
0223 # if N
0224 # define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
0225 # define BOOST_PP_LOCAL_LIMITS (0, N-1)
0226 # include BOOST_PP_LOCAL_ITERATE()
0227 # endif
0228
0229
0230 if (!m_data.second().precall(inner_args))
0231 return 0;
0232
0233 PyObject* result = detail::invoke(
0234 detail::invoke_tag<result_t,F>()
0235 , create_result_converter(args_, (result_converter*)0, (result_converter*)0)
0236 , m_data.first()
0237 BOOST_PP_ENUM_TRAILING_PARAMS(N, c)
0238 );
0239
0240 return m_data.second().postcall(inner_args, result);
0241 }
0242
0243 static unsigned min_arity() { return N; }
0244
0245 static py_func_sig_info signature()
0246 {
0247 const signature_element * sig = detail::signature<Sig>::elements();
0248 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
0249
0250
0251
0252 const signature_element * ret = detail::get_ret<Policies, Sig>();
0253
0254 py_func_sig_info res = {sig, ret };
0255 #else
0256 py_func_sig_info res = {sig, sig };
0257 #endif
0258
0259 return res;
0260 }
0261 private:
0262 compressed_pair<F,Policies> m_data;
0263 };
0264 };
0265
0266
0267
0268 #endif
0269
0270