From f355be8ac5abeed3d9421d6bd8b5ecfe922d51cc Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 16 Sep 2002 02:50:22 +0000 Subject: [PATCH] moved to python_v2_API_restructure branch [SVN r15353] --- include/boost/python/class.hpp | 109 ++---- include/boost/python/def.hpp | 48 ++- include/boost/python/detail/defaults_def.hpp | 13 +- include/boost/python/detail/defaults_gen.hpp | 370 ++++++++++++------- include/boost/python/init.hpp | 111 +++++- include/boost/python/module.hpp | 3 +- 6 files changed, 378 insertions(+), 276 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 7f769739..9c4d01c2 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -46,7 +46,7 @@ namespace detail struct write_type_id { write_type_id(type_info**p) : p(p) {} - + // Here's the runtime behavior template void operator()(T*) const @@ -85,15 +85,7 @@ namespace detail SelectHolder::register_(); } - template - struct assert_default_constructible - { - static int check2(T const&); - static int check() - { - return sizeof(check2(T())); - } - }; + template int assert_default_constructible(T const&); } // @@ -153,8 +145,8 @@ class class_ : public objects::class_base public: // Automatically derive the class name - only works on some // compilers because type_info::name is sometimes mangled (gcc) - class_(); // With default-constructor init function - class_(no_init_t); // With no init function +// class_(); // With default-constructor init function +// class_(no_init_t); // With no init function // Construct with the class name, with or without docstring, and default init() function class_(char const* name, char const* doc = 0); @@ -165,22 +157,21 @@ class class_ : public objects::class_base // Construct with class name, docstring, and no init() function class_(char const* name, char const* doc, no_init_t); - template - inline class_(char const* name, detail::args_base const&) + template + inline class_(char const* name, init_base const& i) : base(name, id_vector::size, id_vector().ids) { this->register_(); - this->def_init(InitArgs()); + define_init(*this, i.derived()); this->set_instance_size(holder_selector::additional_size()); } - - template - inline class_(char const* name, char const* doc, detail::args_base const&, char const* initdoc = 0) + template + inline class_(char const* name, char const* doc, init_base const& i) : base(name, id_vector::size, id_vector().ids, doc) { this->register_(); - this->def_init(InitArgs(), initdoc); + define_init(*this, i.derived()); this->set_instance_size(holder_selector::additional_size()); } @@ -194,23 +185,10 @@ class class_ : public objects::class_base return *this; } - template - self& def(init const& i) + template + self& def(init_base const& i) { - define_init(*this, i, default_call_policies(), 0); - return *this; - } - - template - self& def( - init const& i, - CallPolicyOrDoc const& policy_or_doc, - char const* doc = 0) - { - typedef detail::def_helper helper; - define_init(*this, i, - helper::get_policy(policy_or_doc), - helper::get_doc(policy_or_doc, doc)); + define_init(*this, i.derived()); return *this; } @@ -218,37 +196,25 @@ class class_ : public objects::class_base self& def(char const* name, Arg1T arg1, Arg2T const& arg2) { // The arguments may be: - // arg1: function or signature - // arg2: policy or docstring or stubs + // def(name, function) + // def(name, function, policy) + // def(name, function, doc_string) + // def(name, signature, stubs) - dispatch_def(&arg2, name, arg1, arg2, (char*)0); + dispatch_def(&arg2, name, arg1, arg2); return *this; } template self& def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3) { - // The arguments may be: - // arg1: function or signature - // arg2: policy or docstring or stubs - // arg3: policy or docstring + // The arguments are definitely: + // def(name, function, policy, doc_string) // TODO: exchange policy, doc_string position dispatch_def(&arg2, name, arg1, arg2, arg3); return *this; } - template - self& def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, char const* doc) - { - // The arguments are definitely: - // arg1: signature - // arg2: stubs - // arg3: policy - - dispatch_def(&arg2, name, arg1, arg2, arg3, doc); - return *this; - } - template self& def(detail::operator_ const& op) { @@ -288,7 +254,6 @@ class class_ : public objects::class_base // Define the default constructor. self& def_init() { - detail::assert_default_constructible::check(); this->def_init(mpl::list0<>::type()); return *this; } @@ -375,7 +340,7 @@ class class_ : public objects::class_base char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, - char const* doc) + char const* doc = 0) { typedef detail::def_helper helper; @@ -385,23 +350,17 @@ class class_ : public objects::class_base } - template + template void dispatch_def( detail::func_stubs_base const*, char const* name, SigT sig, - StubsT const& stubs, - CallPolicyOrDoc const& policy_or_doc, - char const* doc = 0) + StubsT const& stubs) { - typedef detail::def_helper helper; - // convert sig to a type_list (see detail::get_signature in signature.hpp) // before calling detail::define_with_defaults. detail::define_with_defaults( - name, stubs, helper::get_policy(policy_or_doc), - *this, detail::get_signature(sig), - helper::get_doc(policy_or_doc, doc)); + name, stubs, *this, detail::get_signature(sig)); } }; @@ -421,30 +380,12 @@ inline void class_::register_() const ); } - - -template -inline class_::class_() - : base(typeid(T).name(), id_vector::size, id_vector().ids) -{ - this->register_(); - this->def_init(); - this->set_instance_size(holder_selector::additional_size()); -} - -template -inline class_::class_(no_init_t) - : base(typeid(T).name(), id_vector::size, id_vector().ids) -{ - this->register_(); - this->def_no_init(); -} - template inline class_::class_(char const* name, char const* doc) : base(name, id_vector::size, id_vector().ids, doc) { this->register_(); + detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); this->def_init(); this->set_instance_size(holder_selector::additional_size()); } diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index c6b8bb54..c581e7f6 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -26,7 +26,7 @@ namespace detail char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, - char const* doc) + char const* doc = 0) { typedef detail::def_helper helper; @@ -35,25 +35,19 @@ namespace detail helper::get_doc(policy_or_doc, doc)); } - template + template void dispatch_def( detail::func_stubs_base const*, char const* name, SigT sig, - StubsT const& stubs, - CallPolicyOrDoc const& policy_or_doc, - char const* doc = 0) + StubsT const& stubs) { - typedef detail::def_helper helper; - // convert sig to a type_list (see detail::get_signature in signature.hpp) // before calling detail::define_with_defaults. scope current; detail::define_with_defaults( - name, stubs, helper::get_policy(policy_or_doc), - current, detail::get_signature(sig), - helper::get_doc(policy_or_doc, doc)); + name, stubs, current, detail::get_signature(sig)); } } @@ -67,33 +61,33 @@ template void def(char const* name, Arg1T arg1, Arg2T const& arg2) { // The arguments may be: - // arg1: function or signature - // arg2: policy or docstring or stubs + // def(name, function) + // def(name, function, policy) + // def(name, function, doc_string) + // def(name, signature, stubs) - detail::dispatch_def(&arg2, name, arg1, arg2, (char*)0); + detail::dispatch_def(&arg2, name, arg1, arg2); } template void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3) { - // The arguments may be: - // arg1: function or signature - // arg2: policy or docstring or stubs - // arg3: policy or docstring + // The arguments are definitely: + // def(name, function, policy, doc_string) // TODO: exchange policy, doc_string position detail::dispatch_def(&arg2, name, arg1, arg2, arg3); } -template -void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, char const* doc) -{ - // The arguments are definitely: - // arg1: signature - // arg2: stubs - // arg3: policy - - detail::dispatch_def(&arg2, name, arg1, arg2, arg3, doc); -} +//template +//void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, char const* doc) +//{ +// // The arguments are definitely: +// // arg1: signature +// // arg2: stubs +// // arg3: policy +// +// detail::dispatch_def(&arg2, name, arg1, arg2, arg3, doc); +//} }} // namespace boost::python diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 9c79d926..a8e32c8a 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -191,15 +191,13 @@ struct define_stub_function {}; // void C::foo(int) mpl::list // /////////////////////////////////////////////////////////////////////////////// - template + template inline void define_with_defaults( char const* name, - StubsT, - CallPolicies const& policies, + StubsT const& stubs, NameSpaceT& name_space, - SigT sig, - char const* doc) + SigT sig) { typedef typename mpl::front::type return_type; typedef typename StubsT::v_type v_type; @@ -216,7 +214,7 @@ struct define_stub_function {}; typedef typename stubs_type::template gen gen_type; define_with_defaults_helper::def - (name, gen_type(), policies, name_space, doc); + (name, gen_type(), stubs.call_policies(), name_space, stubs.doc_string()); } } // namespace detail @@ -238,8 +236,7 @@ struct define_stub_function { StubsT, CallPolicies const& policies, NameSpaceT& name_space, - char const* doc - ) + char const* doc) { detail::name_space_def(name_space, name, diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 78808424..e20841c5 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -12,12 +12,12 @@ #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -26,164 +26,262 @@ #include #include -namespace boost { namespace python { namespace detail { +namespace boost { namespace python { /////////////////////////////////////////////////////////////////////////////// // // func_stubs_base is used as a base class for all function stubs. // /////////////////////////////////////////////////////////////////////////////// -struct func_stubs_base {}; - -}}} // namespace boost::python::detail - - -/////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_TYPEDEF_GEN(z, INDEX, DATA) \ - typedef typename ::boost::mpl::at_c \ - < \ - BOOST_PP_ADD_D(1, INDEX, DATA), \ - SigT \ - >::type BOOST_PP_CAT(T, INDEX); \ - -#define BPL_IMPL_FUNC_WRAPPER_GEN(z, index, DATA) \ - static RT BOOST_PP_CAT(func_, index) ( \ - BOOST_PYTHON_BINARY_ENUM( \ - BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), T, arg) \ - ) \ - { \ - BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ - BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ - ( \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), \ - arg \ - ) \ - ); \ + namespace detail + { + struct func_stubs_base {}; } -#define BPL_IMPL_GEN_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ - struct FSTUBS_NAME { \ +template +struct func_stubs_with_call_policies +: public detail::func_stubs_base +{ + typedef typename StubsT::nv_type nv_type; + typedef typename StubsT::v_type v_type; + + func_stubs_with_call_policies(CallPoliciesT const& policies_, char const* doc_) + : policies(policies_), doc(doc_) {} + + char const* doc_string() const + { return doc; } + + CallPoliciesT + call_policies() const + { return policies; } + + CallPoliciesT policies; + char const* doc; +}; + +}} // namespace boost::python + +/////////////////////////////////////////////////////////////////////////////// +#define BOOST_PYTHON_TYPEDEF_GEN(z, index, data) \ + typedef typename BOOST_PP_CAT(iter, index)::next \ + BOOST_PP_CAT(iter, BOOST_PP_INC(index)); \ + typedef typename 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_PYTHON_BINARY_ENUM( \ + 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, n_funcs = BOOST_PP_INC(n_dflts)); \ BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \ \ template \ struct gen { \ \ - typedef typename ::boost::mpl::front::type RT; \ + typedef typename ::boost::mpl::begin::type rt_iter; \ + typedef typename rt_iter::type RT; \ + typedef typename rt_iter::next iter0; \ \ - BOOST_PP_REPEAT_2ND \ - ( \ - N_ARGS, \ - BPL_IMPL_TYPEDEF_GEN, \ - 1 \ - ) \ + BOOST_PP_REPEAT_2ND( \ + n_args, \ + BOOST_PYTHON_TYPEDEF_GEN, \ + 0) \ \ - BOOST_PP_REPEAT_2ND \ - ( \ - BOOST_PP_INC(N_DFLTS), \ - BPL_IMPL_FUNC_WRAPPER_GEN, \ - (FNAME, BOOST_PP_SUB_D(1, N_ARGS, N_DFLTS), RETURN) \ - ) \ + BOOST_PP_REPEAT_FROM_TO( \ + 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 BPL_IMPL_MEM_FUNC_WRAPPER_GEN(z, index, DATA) \ - static RT BOOST_PP_CAT(func_, index) ( \ - ClassT& obj BOOST_PP_COMMA_IF( \ - BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index)) \ - BOOST_PYTHON_BINARY_ENUM( \ - BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), T, arg) \ +#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_PYTHON_BINARY_ENUM(index, T, arg) \ ) \ { \ - BOOST_PP_TUPLE_ELEM(3, 2, DATA) obj.BOOST_PP_TUPLE_ELEM(3, 0, DATA)( \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), arg \ - ) \ + BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)( \ + BOOST_PP_ENUM_PARAMS(index, arg) \ ); \ } -#define BPL_IMPL_GEN_MEM_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ - struct FSTUBS_NAME { \ - \ - BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(N_DFLTS)); \ - BOOST_STATIC_CONSTANT(int, max_args = n_funcs + 1); \ - \ - template \ - struct gen { \ - \ - typedef typename ::boost::mpl::front::type RT; \ - typedef typename ::boost::mpl::at_c<1, SigT>::type ClassT; \ - \ - BOOST_PP_REPEAT_2ND \ - ( \ - N_ARGS, \ - BPL_IMPL_TYPEDEF_GEN, \ - 2 \ - ) \ - \ - BOOST_PP_REPEAT_2ND \ - ( \ - BOOST_PP_INC(N_DFLTS), \ - BPL_IMPL_MEM_FUNC_WRAPPER_GEN, \ - (FNAME, BOOST_PP_SUB_D(1, N_ARGS, N_DFLTS), RETURN) \ - ) \ - }; \ +#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 \ + struct gen { \ + \ + typedef typename ::boost::mpl::begin::type rt_iter; \ + typedef typename rt_iter::type RT; \ + \ + typedef typename rt_iter::next class_iter; \ + typedef typename class_iter::type ClassT; \ + typedef typename class_iter::next iter0; \ + \ + BOOST_PP_REPEAT_2ND( \ + n_args, \ + BOOST_PYTHON_TYPEDEF_GEN, \ + 0) \ + \ + BOOST_PP_REPEAT_FROM_TO( \ + 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)) \ + }; \ }; - /////////////////////////////////////////////////////////////////////////////// #if defined(BOOST_MSVC) -#define BPL_IMPL_GEN_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ - BPL_IMPL_GEN_FUNCTION \ - (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ - BPL_IMPL_GEN_FUNCTION \ - (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \ - struct FSTUBS_NAME \ +#define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + BOOST_PYTHON_GEN_FUNCTION \ + (fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \ + BOOST_PYTHON_GEN_FUNCTION \ + (fname, BOOST_PP_CAT(fstubs_name, _V), n_args, n_dflts, ;) \ + struct fstubs_name \ : public boost::python::detail::func_stubs_base { \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) nv_type; \ + typedef BOOST_PP_CAT(fstubs_name, _V) v_type; \ + typedef fstubs_name self_t; \ + \ + fstubs_name(char const* doc_ = 0) \ + : doc(doc_) {} \ + \ + char const* doc_string() const \ + { return doc; } \ + \ + default_call_policies \ + call_policies() const \ + { return default_call_policies(); } \ + \ + template \ + func_stubs_with_call_policies \ + operator[](CallPoliciesT const& policies) const \ + { \ + return func_stubs_with_call_policies \ + (policies, doc); \ + } \ + \ + char const* doc; \ }; \ /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_GEN_MEM_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ - BPL_IMPL_GEN_MEM_FUNCTION \ - (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ - BPL_IMPL_GEN_MEM_FUNCTION \ - (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \ - struct FSTUBS_NAME \ +#define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + BOOST_PYTHON_GEN_MEM_FUNCTION \ + (fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \ + BOOST_PYTHON_GEN_MEM_FUNCTION \ + (fname, BOOST_PP_CAT(fstubs_name, _V), n_args, n_dflts, ;) \ + struct fstubs_name \ : public boost::python::detail::func_stubs_base { \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) nv_type; \ + typedef BOOST_PP_CAT(fstubs_name, _V) v_type; \ + typedef fstubs_name self_t; \ + \ + fstubs_name(char const* doc_ = 0) \ + : doc(doc_) {} \ + \ + char const* doc_string() const \ + { return doc; } \ + \ + default_call_policies \ + call_policies() const \ + { return default_call_policies(); } \ + \ + template \ + func_stubs_with_call_policies \ + operator[](CallPoliciesT const& policies) const \ + { \ + return func_stubs_with_call_policies \ + (policies, doc); \ + } \ + \ + char const* doc; \ }; \ #else /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_GEN_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ - BPL_IMPL_GEN_FUNCTION \ - (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ - struct FSTUBS_NAME \ +#define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + BOOST_PYTHON_GEN_FUNCTION \ + (fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \ + struct fstubs_name \ : public boost::python::detail::func_stubs_base { \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) nv_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) v_type; \ + typedef fstubs_name self_t; \ + \ + fstubs_name(char const* doc_ = 0) \ + : doc(doc_) {} \ + \ + char const* doc_string() const \ + { return doc; } \ + \ + default_call_policies \ + call_policies() const \ + { return default_call_policies(); } \ + \ + template \ + func_stubs_with_call_policies \ + operator[](CallPoliciesT const& policies) const \ + { \ + return func_stubs_with_call_policies \ + (policies, doc); \ + } \ + \ + char const* doc; \ }; \ /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_GEN_MEM_FUNCTION_STUB(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS) \ - BPL_IMPL_GEN_MEM_FUNCTION \ - (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ - struct FSTUBS_NAME \ +#define BOOST_PYTHON_GEN_MEM_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + BOOST_PYTHON_GEN_MEM_FUNCTION \ + (fname, BOOST_PP_CAT(fstubs_name, _NV), n_args, n_dflts, return) \ + struct fstubs_name \ : public boost::python::detail::func_stubs_base { \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) nv_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) v_type; \ + typedef fstubs_name self_t; \ + \ + fstubs_name(char const* doc_ = 0) \ + : doc(doc_) {} \ + \ + char const* doc_string() const \ + { return doc; } \ + \ + default_call_policies \ + call_policies() const \ + { return default_call_policies(); } \ + \ + template \ + func_stubs_with_call_policies \ + operator[](CallPoliciesT const& policies) const \ + { \ + return func_stubs_with_call_policies \ + (policies, doc); \ + } \ + \ + char const* doc; \ }; \ #endif // defined(BOOST_MSVC) @@ -192,11 +290,11 @@ struct func_stubs_base {}; // // MAIN MACROS // -// Given GENERATOR_NAME, FNAME, MIN_ARGS and MAX_ARGS, These 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. +// 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: // @@ -225,11 +323,17 @@ struct func_stubs_base {}; // template // struct gen { // -// typedef typename ::boost::mpl::at_c<0, SigT>::type RT; -// typedef typename ::boost::mpl::at_c<1, SigT>::type T0; -// typedef typename ::boost::mpl::at_c<2, SigT>::type T1; -// typedef typename ::boost::mpl::at_c<3, SigT>::type T2; -// typedef typename ::boost::mpl::at_c<4, SigT>::type T3; +// typedef typename ::boost::mpl::begin::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); } @@ -260,23 +364,19 @@ struct func_stubs_base {}; // for the return type (void) and the lack of the return keyword. // /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_FUNCTION_OVERLOADS(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS) \ - BPL_IMPL_GEN_FUNCTION_STUB \ - ( \ - FNAME, \ - GENERATOR_NAME, \ - MAX_ARGS, \ - BOOST_PP_SUB_D(1, MAX_ARGS, MIN_ARGS) \ - ) +#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) \ - BPL_IMPL_GEN_MEM_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 diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 733973b1..824b72f0 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -36,26 +36,20 @@ /////////////////////////////////////////////////////////////////////////////// #define BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT \ - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT \ - ( \ + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ BOOST_PYTHON_MAX_ARITY, \ class T, \ - mpl::void_ \ - ) \ + mpl::void_) \ #define BOOST_PYTHON_TEMPLATE_TYPES \ - BOOST_PP_ENUM_PARAMS \ - ( \ + BOOST_PP_ENUM_PARAMS( \ BOOST_PYTHON_MAX_ARITY, \ - class T \ - ) \ + class T) \ #define BOOST_PYTHON_TEMPLATE_ARGS \ - BOOST_PP_ENUM_PARAMS \ - ( \ + BOOST_PP_ENUM_PARAMS( \ BOOST_PYTHON_MAX_ARITY, \ - T \ - ) \ + T) \ /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { @@ -94,7 +88,7 @@ namespace detail { bool, value = sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); typedef mpl::bool_c type; - + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) // needed for MSVC & Borland }; @@ -123,10 +117,56 @@ namespace detail { } // namespace detail +template +struct init_base { + + DerivedT const& derived() const + { return *static_cast(this); } +}; + +template +struct init_with_call_policies +: public init_base > +{ + BOOST_STATIC_CONSTANT(int, n_arguments = InitT::n_arguments); + BOOST_STATIC_CONSTANT(int, n_defaults = InitT::n_defaults); + + typedef typename InitT::reversed_args reversed_args; + + init_with_call_policies(CallPoliciesT const& policies_, char const* doc_) + : policies(policies_), doc(doc_) {} + + char const* doc_string() const + { return doc; } + + CallPoliciesT + call_policies() const + { return policies; } + + CallPoliciesT policies; + char const* doc; +}; template -struct init //: detail::check_init_params +struct init : public init_base > { + typedef init self_t; + + init(char const* doc_ = 0) + : doc(doc_) {} + + char const* doc_string() const + { return doc; } + + default_call_policies + call_policies() const + { return default_call_policies(); } + + template + init_with_call_policies + operator[](CallPoliciesT const& policies) const + { return init_with_call_policies(policies, doc); } + typedef detail::type_list signature_; typedef typename mpl::end::type finish; @@ -143,7 +183,7 @@ struct init //: detail::check_init_params , mpl::next >::type expected_finish; BOOST_STATIC_ASSERT((is_same::value)); - + typedef typename mpl::apply_if< is_same , mpl::list0<> @@ -173,6 +213,36 @@ struct init //: detail::check_init_params // Count the maximum number of arguments BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); + + char const* doc; +}; + +template <> // specialization for zero args +struct init<> : public init_base > +{ + typedef init<> self_t; + + init(char const* doc_ = 0) + : doc(doc_) {} + + char const* doc_string() const + { return doc; } + + default_call_policies + call_policies() const + { return default_call_policies(); } + + template + init_with_call_policies + operator[](CallPoliciesT const& policies) const + { return init_with_call_policies(policies, doc); } + + BOOST_STATIC_CONSTANT(int, n_defaults = 0); + BOOST_STATIC_CONSTANT(int, n_arguments = 0); + + typedef detail::type_list<> reversed_args; + + char const* doc; }; /////////////////////////////////////////////////////////////////////////////// @@ -198,10 +268,10 @@ namespace detail , mpl::list0<> , mpl::push_front >::type args; - + cl.def_init(args(), policies, doc); } - + /////////////////////////////////////////////////////////////////////////////// // // define_class_init_helper::apply @@ -269,12 +339,13 @@ namespace detail // __init__(int) // /////////////////////////////////////////////////////////////////////////////// -template +template void -define_init(ClassT& cl, InitT const& i, CallPoliciesT const& policies, char const* doc) +define_init(ClassT& cl, InitT const& i) { typedef typename InitT::reversed_args reversed_args; - detail::define_class_init_helper::apply(cl, policies, reversed_args(), doc); + detail::define_class_init_helper::apply( + cl, i.call_policies(), reversed_args(), i.doc_string()); } }} // namespace boost::python diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index a455ca41..9f5f4d21 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -90,8 +90,7 @@ class module : public detail::module_base // convert sig to a type_list (see detail::get_signature in signature.hpp) // before calling detail::define_with_defaults. detail::define_with_defaults( - name, stubs, default_call_policies(), - *this, detail::get_signature(sig), doc); + name, stubs, *this, detail::get_signature(sig)); } };