389 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			389 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /////////////////////////////////////////////////////////////////////////////// | ||
|  | // | ||
|  | // Copyright David Abrahams 2002, Joel de Guzman, 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 DEFAULTS_GEN_JDG20020807_HPP | ||
|  | #define DEFAULTS_GEN_JDG20020807_HPP | ||
|  | 
 | ||
|  | #include <boost/python/detail/preprocessor.hpp> | ||
|  | #include <boost/preprocessor/repeat.hpp> | ||
|  | #include <boost/preprocessor/repeat_from_to.hpp> | ||
|  | #include <boost/preprocessor/enum.hpp> | ||
|  | #include <boost/preprocessor/enum_params.hpp> | ||
|  | #include <boost/preprocessor/repetition/enum_binary_params.hpp> | ||
|  | #include <boost/preprocessor/tuple.hpp> | ||
|  | #include <boost/preprocessor/cat.hpp> | ||
|  | #include <boost/preprocessor/arithmetic/sub.hpp> | ||
|  | #include <boost/preprocessor/stringize.hpp> | ||
|  | #include <boost/preprocessor/inc.hpp> | ||
|  | #include <boost/preprocessor/empty.hpp> | ||
|  | #include <boost/preprocessor/comma_if.hpp> | ||
|  | #include <boost/config.hpp> | ||
|  | #include <boost/mpl/begin_end.hpp> | ||
|  | #include <boost/mpl/next.hpp> | ||
|  | #include <boost/mpl/deref.hpp> | ||
|  | #include <cstddef> | ||
|  | 
 | ||
|  | namespace boost { namespace python { | ||
|  | 
 | ||
|  | namespace detail | ||
|  | { | ||
|  |   // overloads_base is used as a base class for all function | ||
|  |   // stubs. This class holds the doc_string of the stubs. | ||
|  |   struct overloads_base | ||
|  |   { | ||
|  |       overloads_base(char const* doc_) | ||
|  |           : m_doc(doc_) {} | ||
|  | 
 | ||
|  |       overloads_base(char const* doc_, detail::keyword_range const& kw) | ||
|  |           : m_doc(doc_), m_keywords(kw) {} | ||
|  | 
 | ||
|  |       char const* doc_string() const | ||
|  |       { | ||
|  |           return m_doc; | ||
|  |       } | ||
|  | 
 | ||
|  |       detail::keyword_range const& keywords() const | ||
|  |       { | ||
|  |           return m_keywords; | ||
|  |       } | ||
|  | 
 | ||
|  |    private: | ||
|  |       char const* m_doc; | ||
|  |       detail::keyword_range m_keywords; | ||
|  |   }; | ||
|  | 
 | ||
|  |   // overloads_proxy is generated by the overloads_common operator[] (see | ||
|  |   // below). This class holds a user defined call policies of the stubs. | ||
|  |   template <class CallPoliciesT, class OverloadsT> | ||
|  |   struct overloads_proxy | ||
|  |       : public overloads_base | ||
|  |   { | ||
|  |       typedef typename OverloadsT::non_void_return_type   non_void_return_type; | ||
|  |       typedef typename OverloadsT::void_return_type       void_return_type; | ||
|  | 
 | ||
|  |       overloads_proxy( | ||
|  |           CallPoliciesT const& policies_ | ||
|  |           , char const* doc | ||
|  |           , keyword_range const& kw | ||
|  |           ) | ||
|  |           : overloads_base(doc, kw) | ||
|  |             , policies(policies_) | ||
|  |       {} | ||
|  | 
 | ||
|  |       CallPoliciesT | ||
|  |       call_policies() const | ||
|  |       { | ||
|  |           return policies; | ||
|  |       } | ||
|  | 
 | ||
|  |       CallPoliciesT policies; | ||
|  |   }; | ||
|  | 
 | ||
|  |   // overloads_common is our default function stubs base class. This | ||
|  |   // class returns the default_call_policies in its call_policies() | ||
|  |   // member function.  It can generate a overloads_proxy however through | ||
|  |   // its operator[] | ||
|  |   template <class DerivedT> | ||
|  |   struct overloads_common | ||
|  |       : public overloads_base | ||
|  |   { | ||
|  |       overloads_common(char const* doc) | ||
|  |           : overloads_base(doc) {} | ||
|  | 
 | ||
|  |       overloads_common(char const* doc, keyword_range const& kw) | ||
|  |           : overloads_base(doc, kw) {} | ||
|  | 
 | ||
|  |       default_call_policies | ||
|  |       call_policies() const | ||
|  |       { | ||
|  |           return default_call_policies(); | ||
|  |       } | ||
|  | 
 | ||
|  |       template <class CallPoliciesT> | ||
|  |       overloads_proxy<CallPoliciesT, DerivedT> | ||
|  |       operator[](CallPoliciesT const& policies) const | ||
|  |       { | ||
|  |           return overloads_proxy<CallPoliciesT, DerivedT>( | ||
|  |               policies, this->doc_string(), this->keywords()); | ||
|  |       } | ||
|  |   }; | ||
|  | 
 | ||
|  | }}} // namespace boost::python::detail | ||
|  | 
 | ||
|  | 
 | ||
|  | #define BOOST_PYTHON_TYPEDEF_GEN(z, index, data)                                \ | ||
|  |     typedef typename ::boost::mpl::next<BOOST_PP_CAT(iter, index)>::type        \ | ||
|  |         BOOST_PP_CAT(iter, BOOST_PP_INC(index));                                \ | ||
|  |     typedef typename ::boost::mpl::deref<BOOST_PP_CAT(iter, index)>::type       \ | ||
|  |         BOOST_PP_CAT(T, index); | ||
|  | 
 | ||
|  | #define BOOST_PYTHON_FUNC_WRAPPER_GEN(z, index, data)                   \ | ||
|  |     static RT BOOST_PP_CAT(func_,                                       \ | ||
|  |         BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) (    \ | ||
|  |         BOOST_PP_ENUM_BINARY_PARAMS_Z(                                  \ | ||
|  |             1, index, T, arg))                                          \ | ||
|  |     {                                                                   \ | ||
|  |         BOOST_PP_TUPLE_ELEM(3, 2, data)                                 \ | ||
|  |         BOOST_PP_TUPLE_ELEM(3, 0, data)(                                \ | ||
|  |             BOOST_PP_ENUM_PARAMS(                                       \ | ||
|  |                 index,                                                  \ | ||
|  |                 arg));                                                  \ | ||
|  |     } | ||
|  | 
 | ||
|  | #define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret)     \ | ||
|  |     struct fstubs_name                                                          \ | ||
|  |     {                                                                           \ | ||
|  |         BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts));            \ | ||
|  |         BOOST_STATIC_CONSTANT(int, max_args = n_funcs);                         \ | ||
|  |                                                                                 \ | ||
|  |         template <typename SigT>                                                \ | ||
|  |         struct gen                                                              \ | ||
|  |         {                                                                       \ | ||
|  |             typedef typename ::boost::mpl::begin<SigT>::type rt_iter;           \ | ||
|  |             typedef typename ::boost::mpl::deref<rt_iter>::type RT;             \ | ||
|  |             typedef typename ::boost::mpl::next<rt_iter>::type iter0;           \ | ||
|  |                                                                                 \ | ||
|  |             BOOST_PP_REPEAT_2ND(                                                \ | ||
|  |                 n_args,                                                         \ | ||
|  |                 BOOST_PYTHON_TYPEDEF_GEN,                                       \ | ||
|  |                 0)                                                              \ | ||
|  |                                                                                 \ | ||
|  |             BOOST_PP_REPEAT_FROM_TO_2(                                          \ | ||
|  |                 BOOST_PP_SUB_D(1, n_args, n_dflts),                             \ | ||
|  |                 BOOST_PP_INC(n_args),                                           \ | ||
|  |                 BOOST_PYTHON_FUNC_WRAPPER_GEN,                                  \ | ||
|  |                 (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret))               \ | ||
|  |         };                                                                      \ | ||
|  |     };                                                                          \ | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | #define BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN(z, index, data)                       \ | ||
|  |     static RT BOOST_PP_CAT(func_,                                               \ | ||
|  |         BOOST_PP_SUB_D(1, index, BOOST_PP_TUPLE_ELEM(3, 1, data))) (            \ | ||
|  |             ClassT obj BOOST_PP_COMMA_IF(index)                                 \ | ||
|  |             BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg)                     \ | ||
|  |         )                                                                       \ | ||
|  |     {                                                                           \ | ||
|  |         BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)(    \ | ||
|  |             BOOST_PP_ENUM_PARAMS(index, arg)                                    \ | ||
|  |         );                                                                      \ | ||
|  |     } | ||
|  | 
 | ||
|  | #define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ | ||
|  |     struct fstubs_name                                                          \ | ||
|  |     {                                                                           \ | ||
|  |         BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts));            \ | ||
|  |         BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1);                     \ | ||
|  |                                                                                 \ | ||
|  |         template <typename SigT>                                                \ | ||
|  |         struct gen                                                              \ | ||
|  |         {                                                                       \ | ||
|  |             typedef typename ::boost::mpl::begin<SigT>::type rt_iter;           \ | ||
|  |             typedef typename ::boost::mpl::deref<rt_iter>::type RT;             \ | ||
|  |                                                                                 \ | ||
|  |             typedef typename ::boost::mpl::next<rt_iter>::type class_iter;      \ | ||
|  |             typedef typename ::boost::mpl::deref<class_iter>::type ClassT;      \ | ||
|  |             typedef typename ::boost::mpl::next<class_iter>::type iter0;        \ | ||
|  |                                                                                 \ | ||
|  |             BOOST_PP_REPEAT_2ND(                                                \ | ||
|  |                 n_args,                                                         \ | ||
|  |                 BOOST_PYTHON_TYPEDEF_GEN,                                       \ | ||
|  |                 0)                                                              \ | ||
|  |                                                                                 \ | ||
|  |             BOOST_PP_REPEAT_FROM_TO_2(                                          \ | ||
|  |                 BOOST_PP_SUB_D(1, n_args, n_dflts),                             \ | ||
|  |                 BOOST_PP_INC(n_args),                                           \ | ||
|  |                 BOOST_PYTHON_MEM_FUNC_WRAPPER_GEN,                              \ | ||
|  |                 (fname, BOOST_PP_SUB_D(1, n_args, n_dflts), ret))               \ | ||
|  |         };                                                                      \ | ||
|  |     }; | ||
|  | 
 | ||
|  | #define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)                    \ | ||
|  |     fstubs_name(char const* doc = 0)                                                        \ | ||
|  |         : ::boost::python::detail::overloads_common<fstubs_name>(doc) {}                    \ | ||
|  |     template <std::size_t N>                                                                \ | ||
|  |     fstubs_name(char const* doc, ::boost::python::detail::keywords<N> const& keywords)      \ | ||
|  |         : ::boost::python::detail::overloads_common<fstubs_name>(                           \ | ||
|  |             doc, keywords.range())                                                          \ | ||
|  |     {                                                                                       \ | ||
|  |         typedef typename ::boost::python::detail::                                          \ | ||
|  |             error::more_keywords_than_function_arguments<                                   \ | ||
|  |                 N,n_args>::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;              \ | ||
|  |     }                                                                                       \ | ||
|  |     template <std::size_t N>                                                                \ | ||
|  |     fstubs_name(::boost::python::detail::keywords<N> const& keywords, char const* doc = 0)  \ | ||
|  |         : ::boost::python::detail::overloads_common<fstubs_name>(                           \ | ||
|  |             doc, keywords.range())                                                          \ | ||
|  |     {                                                                                       \ | ||
|  |         typedef typename ::boost::python::detail::                                          \ | ||
|  |             error::more_keywords_than_function_arguments<                                   \ | ||
|  |                 N,n_args>::too_many_keywords assertion BOOST_ATTRIBUTE_UNUSED;              \ | ||
|  |     } | ||
|  | 
 | ||
|  | # if defined(BOOST_NO_VOID_RETURNS) | ||
|  | 
 | ||
|  | #  define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)   \ | ||
|  |     struct fstubs_name                                                          \ | ||
|  |         : public ::boost::python::detail::overloads_common<fstubs_name>         \ | ||
|  |     {                                                                           \ | ||
|  |         BOOST_PYTHON_GEN_FUNCTION(                                              \ | ||
|  |             fname, non_void_return_type, n_args, n_dflts, return)               \ | ||
|  |         BOOST_PYTHON_GEN_FUNCTION(                                              \ | ||
|  |             fname, void_return_type, n_args, n_dflts, ;)                        \ | ||
|  |                                                                                 \ | ||
|  |         BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)        \ | ||
|  |     }; | ||
|  | 
 | ||
|  | #  define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)       \ | ||
|  |     struct fstubs_name                                                                  \ | ||
|  |         : public ::boost::python::detail::overloads_common<fstubs_name>                 \ | ||
|  |     {                                                                                   \ | ||
|  |         BOOST_PYTHON_GEN_MEM_FUNCTION(                                                  \ | ||
|  |             fname, non_void_return_type, n_args, n_dflts, return)                       \ | ||
|  |         BOOST_PYTHON_GEN_MEM_FUNCTION(                                                  \ | ||
|  |             fname, void_return_type, n_args, n_dflts, ;)                                \ | ||
|  |                                                                                         \ | ||
|  |         BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts)            \ | ||
|  |     }; | ||
|  | 
 | ||
|  | # else // !defined(BOOST_NO_VOID_RETURNS) | ||
|  | 
 | ||
|  | #  define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)   \ | ||
|  |     struct fstubs_name                                                          \ | ||
|  |         : public ::boost::python::detail::overloads_common<fstubs_name>         \ | ||
|  |     {                                                                           \ | ||
|  |         BOOST_PYTHON_GEN_FUNCTION(                                              \ | ||
|  |             fname, non_void_return_type, n_args, n_dflts, return)               \ | ||
|  |                                                                                 \ | ||
|  |         typedef non_void_return_type void_return_type;                          \ | ||
|  |         BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts)        \ | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  | #  define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)       \ | ||
|  |     struct fstubs_name                                                                  \ | ||
|  |         : public ::boost::python::detail::overloads_common<fstubs_name>                 \ | ||
|  |     {                                                                                   \ | ||
|  |         BOOST_PYTHON_GEN_MEM_FUNCTION(                                                  \ | ||
|  |             fname, non_void_return_type, n_args, n_dflts, return)                       \ | ||
|  |                                                                                         \ | ||
|  |         typedef non_void_return_type void_return_type;                                  \ | ||
|  |         BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args + 1, n_dflts)            \ | ||
|  |     }; | ||
|  | 
 | ||
|  | # endif // !defined(BOOST_NO_VOID_RETURNS) | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | // | ||
|  | //  MAIN MACROS | ||
|  | // | ||
|  | //      Given generator_name, fname, min_args and max_args, These macros | ||
|  | //      generate function stubs that forward to a function or member function | ||
|  | //      named fname. max_args is the arity of the function or member function | ||
|  | //      fname. fname can have default arguments. min_args is the minimum | ||
|  | //      arity that fname can accept. | ||
|  | // | ||
|  | //      There are two versions: | ||
|  | // | ||
|  | //          1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions | ||
|  | //          2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions. | ||
|  | // | ||
|  | //      For instance, given a function: | ||
|  | // | ||
|  | //      int | ||
|  | //      foo(int a, char b = 1, unsigned c = 2, double d = 3) | ||
|  | //      { | ||
|  | //          return a + b + c + int(d); | ||
|  | //      } | ||
|  | // | ||
|  | //      The macro invocation: | ||
|  | // | ||
|  | //          BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) | ||
|  | // | ||
|  | //      Generates this code: | ||
|  | // | ||
|  | //      struct foo_stubsNonVoid | ||
|  | //      { | ||
|  | //          static const int n_funcs = 4; | ||
|  | //          static const int max_args = n_funcs; | ||
|  | // | ||
|  | //          template <typename SigT> | ||
|  | //          struct gen | ||
|  | //          { | ||
|  | //              typedef typename ::boost::mpl::begin<SigT>::type    rt_iter; | ||
|  | //              typedef typename rt_iter::type                      RT; | ||
|  | //              typedef typename rt_iter::next                      iter0; | ||
|  | //              typedef typename iter0::type                        T0; | ||
|  | //              typedef typename iter0::next                        iter1; | ||
|  | //              typedef typename iter1::type                        T1; | ||
|  | //              typedef typename iter1::next                        iter2; | ||
|  | //              typedef typename iter2::type                        T2; | ||
|  | //              typedef typename iter2::next                        iter3; | ||
|  | //              typedef typename iter3::type                        T3; | ||
|  | //              typedef typename iter3::next                        iter4; | ||
|  | // | ||
|  | //              static RT func_0(T0 arg0) | ||
|  | //              { return foo(arg0); } | ||
|  | // | ||
|  | //              static RT func_1(T0 arg0, T1 arg1) | ||
|  | //              { return foo(arg0, arg1); } | ||
|  | // | ||
|  | //              static RT func_2(T0 arg0, T1 arg1, T2 arg2) | ||
|  | //              { return foo(arg0, arg1, arg2); } | ||
|  | // | ||
|  | //              static RT func_3(T0 arg0, T1 arg1, T2 arg2, T3 arg3) | ||
|  | //              { return foo(arg0, arg1, arg2, arg3); } | ||
|  | //          }; | ||
|  | //      }; | ||
|  | // | ||
|  | //      struct foo_overloads | ||
|  | //          : public boost::python::detail::overloads_common<foo_overloads> | ||
|  | //      { | ||
|  | //          typedef foo_overloadsNonVoid    non_void_return_type; | ||
|  | //          typedef foo_overloadsNonVoid    void_return_type; | ||
|  | // | ||
|  | //          foo_overloads(char const* doc = 0) | ||
|  | //             : boost::python::detail::overloads_common<foo_overloads>(doc) {} | ||
|  | //      }; | ||
|  | // | ||
|  | //      The typedefs non_void_return_type and void_return_type are | ||
|  | //      used to handle compilers that do not support void returns. The | ||
|  | //      example above typedefs non_void_return_type and | ||
|  | //      void_return_type to foo_overloadsNonVoid. On compilers that do | ||
|  | //      not support void returns, there are two versions: | ||
|  | //      foo_overloadsNonVoid and foo_overloadsVoid.  The "Void" | ||
|  | //      version is almost identical to the "NonVoid" version except | ||
|  | //      for the return type (void) and the lack of the return keyword. | ||
|  | // | ||
|  | //      See the overloads_common above for a description of the | ||
|  | //      foo_overloads' base class. | ||
|  | // | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | #define BOOST_PYTHON_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args)          \ | ||
|  |     BOOST_PYTHON_GEN_FUNCTION_STUB(                                                         \ | ||
|  |         fname,                                                                              \ | ||
|  |         generator_name,                                                                     \ | ||
|  |         max_args,                                                                           \ | ||
|  |         BOOST_PP_SUB_D(1, max_args, min_args)) | ||
|  | 
 | ||
|  | #define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generator_name, fname, min_args, max_args)   \ | ||
|  |     BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(                                                     \ | ||
|  |         fname,                                                                              \ | ||
|  |         generator_name,                                                                     \ | ||
|  |         max_args,                                                                           \ | ||
|  |         BOOST_PP_SUB_D(1, max_args, min_args)) | ||
|  | 
 | ||
|  | // deprecated macro names (to be removed) | ||
|  | #define BOOST_PYTHON_FUNCTION_GENERATOR BOOST_PYTHON_FUNCTION_OVERLOADS | ||
|  | #define BOOST_PYTHON_MEM_FUN_GENERATOR BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | #endif // DEFAULTS_GEN_JDG20020807_HPP | ||
|  | 
 | ||
|  | 
 |