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