From fe19b492739b8b6d8c54e0bbcd5fa6e8a62c06df Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 13 Aug 2002 12:07:16 +0000 Subject: [PATCH] sprinkled with comments [SVN r14810] --- include/boost/python/detail/defaults_def.hpp | 45 +++++++++++ include/boost/python/detail/defaults_gen.hpp | 84 +++++++++++++++++++- 2 files changed, 126 insertions(+), 3 deletions(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index fd0691c3..6b2d8159 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -21,6 +21,28 @@ namespace boost { namespace python { namespace detail { +/////////////////////////////////////////////////////////////////////////////// +// +// This Boost PP code generates expansions for +// +// template +// inline void +// define_stub_function( +// char const* name, StubsT s, HolderT& holder, boost::mpl::int_t) +// { +// holder.def(name, &StubsT::func_N); +// } +// +// where N runs from 0 to BOOST_PYTHON_MAX_ARITY +// +// The set of overloaded functions (define_stub_function) expects: +// +// 1. char const* name: a python function name +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// 4. int_t: the Nth overloaded function (StubsT::func_N) +// (see defaults_gen.hpp) +// /////////////////////////////////////////////////////////////////////////////// #define BPL_IMPL_STUB_FUNC_DEF(INDEX, DATA) \ \ @@ -39,6 +61,25 @@ namespace detail { BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY) +#undef BPL_IMPL_STUB_FUNC_DEF +/////////////////////////////////////////////////////////////////////////////// +// +// define_with_defaults_helper +// +// This helper template struct does the actual recursive definition +// There's a generic version define_with_defaults_helper and a +// terminal case define_with_defaults_helper<0>. The struct and its +// specialization has a sole static member function def that expect: +// +// 1. char const* name: a python function name +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// +// The def static member function calls a corresponding +// define_stub_function. The general case recursively calls +// define_with_defaults_helper::def until it reaches the +// terminal case case define_with_defaults_helper<0>. +// /////////////////////////////////////////////////////////////////////////////// template struct define_with_defaults_helper { @@ -47,7 +88,9 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY) static void def(char const* name, StubsT stubs, HolderT& holder) { + // define the NTH stub function of stubs define_stub_function(name, stubs, holder, boost::mpl::int_t()); + // call the next define_with_defaults_helper define_with_defaults_helper::def(name, stubs, holder); } }; @@ -60,7 +103,9 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY) static void def(char const* name, StubsT stubs, HolderT& holder) { + // define the Oth stub function of stubs define_stub_function(name, stubs, holder, boost::mpl::int_t<0>()); + // return } }; diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index aeb8bd2c..e807fe52 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -22,9 +22,21 @@ #include #include -/////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { namespace detail { +/////////////////////////////////////////////////////////////////////////////// +// +// func_stubs_base is used as a base class for all function +// stubs. This technique uses the "Curiously recurring template +// pattern" to disambiguate function calls. For instance, the +// interface: +// +// template +// void foo(func_stubs_base const&) +// +// will accept only subclasses of func_stubs_base. +// +/////////////////////////////////////////////////////////////////////////////// template struct func_stubs_base { @@ -225,8 +237,74 @@ struct func_stubs_base { // // 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_GENERATOR for free functions +// 2. BOOST_PYTHON_MEM_FUN_GENERATOR 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_GENERATOR(foo_stubs, foo, 1, 4) +// +// Generates this code: +// +// struct foo_stubs_NV { +// +// static const int n_funcs = 4; +// static const int max_args = n_funcs; +// +// static char const* name() { return "foo"; } +// +// template +// struct gen { +// +// typedef typename mpl::at<0, SigT>::type RT; +// typedef typename mpl::at<1, SigT>::type T0; +// typedef typename mpl::at<2, SigT>::type T1; +// typedef typename mpl::at<3, SigT>::type T2; +// typedef typename mpl::at<4, SigT>::type T3; +// +// 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_stubs +// : public boost::python::detail::func_stubs_base { +// +// typedef foo_stubs_NV nv_type; +// typedef foo_stubs_NV v_type; +// }; +// +// The typedefs nv_type and v_type are used to handle compilers that +// do not support void returns. The example above typedefs nv_type +// and v_type to foo_stubs_NV. On compilers that do not support +// void returns, there are two versions: foo_stubs_NV and foo_stubs_V. +// The "V" version is almost identical to the "NV" version except +// for the return type (void) and the lack of the return keyword. +// /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_FUNCTION_GEN(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS) \ +#define BOOST_PYTHON_FUNCTION_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ BPL_IMPL_GEN_FUNCTION_STUB \ ( \ FNAME, \ @@ -235,7 +313,7 @@ struct func_stubs_base { BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ ) \ -#define BOOST_PYTHON_MEMBER_FUNCTION_GEN(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ +#define BOOST_PYTHON_MEM_FUN_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ BPL_IMPL_GEN_MEM_FUNCTION_STUB \ ( \ FNAME, \