1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/python/detail/caller.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,220 @@
1.4 +#if !defined(BOOST_PP_IS_ITERATING)
1.5 +
1.6 +// Copyright David Abrahams 2002.
1.7 +// Distributed under the Boost Software License, Version 1.0. (See
1.8 +// accompanying file LICENSE_1_0.txt or copy at
1.9 +// http://www.boost.org/LICENSE_1_0.txt)
1.10 +
1.11 +# ifndef CALLER_DWA20021121_HPP
1.12 +# define CALLER_DWA20021121_HPP
1.13 +
1.14 +# include <boost/python/type_id.hpp>
1.15 +# include <boost/python/handle.hpp>
1.16 +
1.17 +# include <boost/python/detail/invoke.hpp>
1.18 +# include <boost/python/detail/signature.hpp>
1.19 +# include <boost/python/detail/preprocessor.hpp>
1.20 +
1.21 +# include <boost/python/arg_from_python.hpp>
1.22 +# include <boost/python/converter/context_result_converter.hpp>
1.23 +
1.24 +# include <boost/preprocessor/iterate.hpp>
1.25 +# include <boost/preprocessor/cat.hpp>
1.26 +# include <boost/preprocessor/dec.hpp>
1.27 +# include <boost/preprocessor/if.hpp>
1.28 +# include <boost/preprocessor/iteration/local.hpp>
1.29 +# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
1.30 +# include <boost/preprocessor/repetition/repeat.hpp>
1.31 +
1.32 +# include <boost/compressed_pair.hpp>
1.33 +
1.34 +# include <boost/type_traits/is_same.hpp>
1.35 +# include <boost/type_traits/is_convertible.hpp>
1.36 +
1.37 +# include <boost/mpl/apply.hpp>
1.38 +# include <boost/mpl/eval_if.hpp>
1.39 +# include <boost/mpl/identity.hpp>
1.40 +# include <boost/mpl/size.hpp>
1.41 +# include <boost/mpl/at.hpp>
1.42 +# include <boost/mpl/int.hpp>
1.43 +# include <boost/mpl/next.hpp>
1.44 +
1.45 +namespace boost { namespace python { namespace detail {
1.46 +
1.47 +template <int N>
1.48 +inline PyObject* get(mpl::int_<N>, PyObject* const& args_)
1.49 +{
1.50 + return PyTuple_GET_ITEM(args_,N);
1.51 +}
1.52 +
1.53 +inline unsigned arity(PyObject* const& args_)
1.54 +{
1.55 + return PyTuple_GET_SIZE(args_);
1.56 +}
1.57 +
1.58 +// This "result converter" is really just used as
1.59 +// a dispatch tag to invoke(...), selecting the appropriate
1.60 +// implementation
1.61 +typedef int void_result_to_python;
1.62 +
1.63 +// Given a model of CallPolicies and a C++ result type, this
1.64 +// metafunction selects the appropriate converter to use for
1.65 +// converting the result to python.
1.66 +template <class Policies, class Result>
1.67 +struct select_result_converter
1.68 + : mpl::eval_if<
1.69 + is_same<Result,void>
1.70 + , mpl::identity<void_result_to_python>
1.71 + , mpl::apply1<typename Policies::result_converter,Result>
1.72 + >
1.73 +{
1.74 +};
1.75 +
1.76 +template <class ArgPackage, class ResultConverter>
1.77 +inline ResultConverter create_result_converter(
1.78 + ArgPackage const& args_
1.79 + , ResultConverter*
1.80 + , converter::context_result_converter*
1.81 +)
1.82 +{
1.83 + return ResultConverter(args_);
1.84 +}
1.85 +
1.86 +template <class ArgPackage, class ResultConverter>
1.87 +inline ResultConverter create_result_converter(
1.88 + ArgPackage const&
1.89 + , ResultConverter*
1.90 + , ...
1.91 +)
1.92 +{
1.93 + return ResultConverter();
1.94 +}
1.95 +
1.96 +template <unsigned> struct caller_arity;
1.97 +
1.98 +template <class F, class CallPolicies, class Sig>
1.99 +struct caller;
1.100 +
1.101 +# define BOOST_PYTHON_NEXT(init,name,n) \
1.102 + typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n;
1.103 +
1.104 +# define BOOST_PYTHON_ARG_CONVERTER(n) \
1.105 + BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \
1.106 + typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \
1.107 + c_t##n c##n(get(mpl::int_<n>(), inner_args)); \
1.108 + if (!c##n.convertible()) \
1.109 + return 0;
1.110 +
1.111 +# define BOOST_PP_ITERATION_PARAMS_1 \
1.112 + (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>))
1.113 +# include BOOST_PP_ITERATE()
1.114 +
1.115 +# undef BOOST_PYTHON_ARG_CONVERTER
1.116 +# undef BOOST_PYTHON_NEXT
1.117 +
1.118 +// A metafunction returning the base class used for caller<class F,
1.119 +// class ConverterGenerators, class CallPolicies, class Sig>.
1.120 +template <class F, class CallPolicies, class Sig>
1.121 +struct caller_base_select
1.122 +{
1.123 + enum { arity = mpl::size<Sig>::value - 1 };
1.124 + typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type;
1.125 +};
1.126 +
1.127 +// A function object type which wraps C++ objects as Python callable
1.128 +// objects.
1.129 +//
1.130 +// Template Arguments:
1.131 +//
1.132 +// F -
1.133 +// the C++ `function object' that will be called. Might
1.134 +// actually be any data for which an appropriate invoke_tag() can
1.135 +// be generated. invoke(...) takes care of the actual invocation syntax.
1.136 +//
1.137 +// CallPolicies -
1.138 +// The precall, postcall, and what kind of resultconverter to
1.139 +// generate for mpl::front<Sig>::type
1.140 +//
1.141 +// Sig -
1.142 +// The `intended signature' of the function. An MPL sequence
1.143 +// beginning with a result type and continuing with a list of
1.144 +// argument types.
1.145 +template <class F, class CallPolicies, class Sig>
1.146 +struct caller
1.147 + : caller_base_select<F,CallPolicies,Sig>::type
1.148 +{
1.149 + typedef typename caller_base_select<
1.150 + F,CallPolicies,Sig
1.151 + >::type base;
1.152 +
1.153 + typedef PyObject* result_type;
1.154 +
1.155 + caller(F f, CallPolicies p) : base(f,p) {}
1.156 +
1.157 +};
1.158 +
1.159 +}}} // namespace boost::python::detail
1.160 +
1.161 +# endif // CALLER_DWA20021121_HPP
1.162 +
1.163 +#else
1.164 +
1.165 +# define N BOOST_PP_ITERATION()
1.166 +
1.167 +template <>
1.168 +struct caller_arity<N>
1.169 +{
1.170 + template <class F, class Policies, class Sig>
1.171 + struct impl
1.172 + {
1.173 + impl(F f, Policies p) : m_data(f,p) {}
1.174 +
1.175 + PyObject* operator()(PyObject* args_, PyObject*) // eliminate
1.176 + // this
1.177 + // trailing
1.178 + // keyword dict
1.179 + {
1.180 + typedef typename mpl::begin<Sig>::type first;
1.181 + typedef typename first::type result_t;
1.182 + typedef typename select_result_converter<Policies, result_t>::type result_converter;
1.183 + typedef typename Policies::argument_package argument_package;
1.184 +
1.185 + argument_package inner_args(args_);
1.186 +
1.187 +# if N
1.188 +# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i)
1.189 +# define BOOST_PP_LOCAL_LIMITS (0, N-1)
1.190 +# include BOOST_PP_LOCAL_ITERATE()
1.191 +# endif
1.192 + // all converters have been checked. Now we can do the
1.193 + // precall part of the policy
1.194 + if (!m_data.second().precall(inner_args))
1.195 + return 0;
1.196 +
1.197 + PyObject* result = detail::invoke(
1.198 + detail::invoke_tag<result_t,F>()
1.199 + , create_result_converter(args_, (result_converter*)0, (result_converter*)0)
1.200 + , m_data.first()
1.201 + BOOST_PP_ENUM_TRAILING_PARAMS(N, c)
1.202 + );
1.203 +
1.204 + return m_data.second().postcall(inner_args, result);
1.205 + }
1.206 +
1.207 + static unsigned min_arity() { return N; }
1.208 +
1.209 + static signature_element const* signature()
1.210 + {
1.211 + return detail::signature<Sig>::elements();
1.212 + }
1.213 +
1.214 + private:
1.215 + compressed_pair<F,Policies> m_data;
1.216 + };
1.217 +};
1.218 +
1.219 +
1.220 +
1.221 +#endif // BOOST_PP_IS_ITERATING
1.222 +
1.223 +