Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/python/detail/caller.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/python/detail/caller.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,259 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +# ifndef CALLER_DWA20021121_HPP +# define CALLER_DWA20021121_HPP + +# include <boost/python/type_id.hpp> +# include <boost/python/handle.hpp> + +# include <boost/detail/indirect_traits.hpp> + +# include <boost/python/detail/invoke.hpp> +# include <boost/python/detail/signature.hpp> +# include <boost/python/detail/preprocessor.hpp> + +# include <boost/python/arg_from_python.hpp> +# include <boost/python/converter/context_result_converter.hpp> +# include <boost/python/converter/builtin_converters.hpp> + +# include <boost/preprocessor/iterate.hpp> +# include <boost/preprocessor/cat.hpp> +# include <boost/preprocessor/dec.hpp> +# include <boost/preprocessor/if.hpp> +# include <boost/preprocessor/iteration/local.hpp> +# include <boost/preprocessor/repetition/enum_trailing_params.hpp> +# include <boost/preprocessor/repetition/repeat.hpp> + +# include <boost/compressed_pair.hpp> + +# include <boost/type_traits/is_same.hpp> +# include <boost/type_traits/is_convertible.hpp> + +# include <boost/mpl/apply.hpp> +# include <boost/mpl/eval_if.hpp> +# include <boost/mpl/identity.hpp> +# include <boost/mpl/size.hpp> +# include <boost/mpl/at.hpp> +# include <boost/mpl/int.hpp> +# include <boost/mpl/next.hpp> + +namespace boost { namespace python { namespace detail { + +template <int N> +inline PyObject* get(mpl::int_<N>, PyObject* const& args_) +{ + return PyTuple_GET_ITEM(args_,N); +} + +inline unsigned arity(PyObject* const& args_) +{ + return PyTuple_GET_SIZE(args_); +} + +// This "result converter" is really just used as +// a dispatch tag to invoke(...), selecting the appropriate +// implementation +typedef int void_result_to_python; + +// Given a model of CallPolicies and a C++ result type, this +// metafunction selects the appropriate converter to use for +// converting the result to python. +template <class Policies, class Result> +struct select_result_converter + : mpl::eval_if< + is_same<Result,void> + , mpl::identity<void_result_to_python> + , mpl::apply1<typename Policies::result_converter,Result> + > +{ +}; + +template <class ArgPackage, class ResultConverter> +inline ResultConverter create_result_converter( + ArgPackage const& args_ + , ResultConverter* + , converter::context_result_converter* +) +{ + return ResultConverter(args_); +} + +template <class ArgPackage, class ResultConverter> +inline ResultConverter create_result_converter( + ArgPackage const& + , ResultConverter* + , ... +) +{ + return ResultConverter(); +} + +#ifndef BOOST_PYTHON_NO_PY_SIGNATURES +template <class ResultConverter> +struct converter_target_type +{ + static PyTypeObject const *get_pytype() + { + return create_result_converter((PyObject*)0, (ResultConverter *)0, (ResultConverter *)0).get_pytype(); + } +}; + +template < > +struct converter_target_type <void_result_to_python > +{ + static PyTypeObject const *get_pytype() + { + return 0; + } +}; +#endif + + +template <unsigned> struct caller_arity; + +template <class F, class CallPolicies, class Sig> +struct caller; + +# define BOOST_PYTHON_NEXT(init,name,n) \ + typedef BOOST_PP_IF(n,typename mpl::next< BOOST_PP_CAT(name,BOOST_PP_DEC(n)) >::type, init) name##n; + +# define BOOST_PYTHON_ARG_CONVERTER(n) \ + BOOST_PYTHON_NEXT(typename mpl::next<first>::type, arg_iter,n) \ + typedef arg_from_python<BOOST_DEDUCED_TYPENAME arg_iter##n::type> c_t##n; \ + c_t##n c##n(get(mpl::int_<n>(), inner_args)); \ + if (!c##n.convertible()) \ + return 0; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY + 1, <boost/python/detail/caller.hpp>)) +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_ARG_CONVERTER +# undef BOOST_PYTHON_NEXT + +// A metafunction returning the base class used for caller<class F, +// class ConverterGenerators, class CallPolicies, class Sig>. +template <class F, class CallPolicies, class Sig> +struct caller_base_select +{ + enum { arity = mpl::size<Sig>::value - 1 }; + typedef typename caller_arity<arity>::template impl<F,CallPolicies,Sig> type; +}; + +// A function object type which wraps C++ objects as Python callable +// objects. +// +// Template Arguments: +// +// F - +// the C++ `function object' that will be called. Might +// actually be any data for which an appropriate invoke_tag() can +// be generated. invoke(...) takes care of the actual invocation syntax. +// +// CallPolicies - +// The precall, postcall, and what kind of resultconverter to +// generate for mpl::front<Sig>::type +// +// Sig - +// The `intended signature' of the function. An MPL sequence +// beginning with a result type and continuing with a list of +// argument types. +template <class F, class CallPolicies, class Sig> +struct caller + : caller_base_select<F,CallPolicies,Sig>::type +{ + typedef typename caller_base_select< + F,CallPolicies,Sig + >::type base; + + typedef PyObject* result_type; + + caller(F f, CallPolicies p) : base(f,p) {} + +}; + +}}} // namespace boost::python::detail + +# endif // CALLER_DWA20021121_HPP + +#else + +# define N BOOST_PP_ITERATION() + +template <> +struct caller_arity<N> +{ + template <class F, class Policies, class Sig> + struct impl + { + impl(F f, Policies p) : m_data(f,p) {} + + PyObject* operator()(PyObject* args_, PyObject*) // eliminate + // this + // trailing + // keyword dict + { + typedef typename mpl::begin<Sig>::type first; + typedef typename first::type result_t; + typedef typename select_result_converter<Policies, result_t>::type result_converter; + typedef typename Policies::argument_package argument_package; + + argument_package inner_args(args_); + +# if N +# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) +# define BOOST_PP_LOCAL_LIMITS (0, N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + // all converters have been checked. Now we can do the + // precall part of the policy + if (!m_data.second().precall(inner_args)) + return 0; + + PyObject* result = detail::invoke( + detail::invoke_tag<result_t,F>() + , create_result_converter(args_, (result_converter*)0, (result_converter*)0) + , m_data.first() + BOOST_PP_ENUM_TRAILING_PARAMS(N, c) + ); + + return m_data.second().postcall(inner_args, result); + } + + static unsigned min_arity() { return N; } + + static py_func_sig_info signature() + { + const signature_element * sig = detail::signature<Sig>::elements(); +#ifndef BOOST_PYTHON_NO_PY_SIGNATURES + + typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type<Sig>::type rtype; + typedef typename select_result_converter<Policies, rtype>::type result_converter; + + static const signature_element ret = { + (boost::is_void<rtype>::value ? "void" : type_id<rtype>().name()) + , &detail::converter_target_type<result_converter>::get_pytype + , boost::detail::indirect_traits::is_reference_to_non_const<rtype>::value + }; + py_func_sig_info res = {sig, &ret }; +#else + py_func_sig_info res = {sig, sig }; +#endif + + return res; + } + private: + compressed_pair<F,Policies> m_data; + }; +}; + + + +#endif // BOOST_PP_IS_ITERATING + +