260 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			260 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								#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 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |