os/ossrv/ossrv_pub/boost_apis/boost/python/detail/caller.hpp
changeset 0 bde4ae8d615e
     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 +