You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
388 lines
20 KiB
388 lines
20 KiB
/////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// 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; \ |
|
} \ |
|
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; \ |
|
} |
|
|
|
# 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 |
|
|
|
|
|
|