From 78ae892db663772fa00a863815f97c9545b3a33c Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 20 Aug 2002 21:09:59 +0000 Subject: [PATCH] Committed the defaults stuff (integrated from v2-dev branch) [SVN r15008] --- include/boost/python/class.hpp | 76 ++++++++++++++++++++++----------- include/boost/python/module.hpp | 46 ++++++++++++++++---- test/Jamfile | 13 +++--- 3 files changed, 96 insertions(+), 39 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index f56bc7b1..a98226f0 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -29,16 +29,18 @@ # include # include # include +# include +# include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { struct write_type_id; - + template struct select_held_type; - + template struct has_noncopyable; @@ -83,21 +85,21 @@ class class_ : public objects::class_base typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); - + typedef typename detail::select_held_type< X1, typename detail::select_held_type< X2, typename detail::select_held_type< X3 >::type>::type>::type held_type; - + typedef objects::class_id class_id; - + typedef typename detail::select_bases::type >::type >::type bases; - + // A helper class which will contain an array of id objects to be // passed to the base class constructor struct id_vector @@ -107,12 +109,12 @@ class class_ : public objects::class_base { // Stick the derived class id into the first element of the array ids[0] = type_id(); - + // Write the rest of the elements into succeeding positions. class_id* p = ids + 1; mpl::for_each::execute(&p); } - + BOOST_STATIC_CONSTANT( std::size_t, size = mpl::size::value + 1); class_id ids[size]; @@ -124,13 +126,13 @@ class class_ : public objects::class_base // compilers because type_info::name is sometimes mangled (gcc) 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); // Construct with class name, no docstring, and no init() function class_(char const* name, no_init_t); - + // Construct with class name, docstring, and no init() function class_(char const* name, char const* doc, no_init_t); @@ -141,8 +143,8 @@ class class_ : public objects::class_base this->register_(); this->def_init(InitArgs()); } - - + + template inline class_(char const* name, char const* doc, detail::args_base const&, char const* initdoc = 0) : base(name, id_vector::size, id_vector().ids, doc) @@ -150,7 +152,7 @@ class class_ : public objects::class_base this->register_(); this->def_init(InitArgs(), initdoc); } - + // Wrap a member function or a non-member function which can take // a T, T cv&, or T cv* as its first parameter, or a callable // python object. @@ -161,14 +163,10 @@ class class_ : public objects::class_base return *this; } - template - self& def(char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0) + template + self& def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0) { - typedef detail::def_helper helper; - - this->def_impl( - name, fn, helper::get_policy(policy_or_doc), helper::get_doc(policy_or_doc, doc), &fn); - + dispatch_def(name, arg1, arg2, doc, &arg2); return *this; } @@ -178,7 +176,7 @@ class class_ : public objects::class_base typedef detail::operator_ op_t; return this->def(op.name(), &op_t::template apply::execute); } - + // Define the constructor with the given Args, which should be an // MPL sequence of types. template @@ -196,7 +194,7 @@ class class_ : public objects::class_base self& def_init(Args const&, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0) { typedef detail::def_helper helper; - + return this->def( "__init__", python::make_constructor( @@ -265,7 +263,7 @@ class class_ : public objects::class_base objects::add_to_namespace( *this, name, make_function( - // This bit of nastiness casts F to a member function of T if possible. + // This bit of nastiness casts F to a member function of T if possible. detail::member_function_cast::stage1(fn).stage2((T*)0).stage3(fn) , policies) , doc); @@ -279,6 +277,34 @@ class class_ : public objects::class_base } inline void register_() const; + + template + void dispatch_def( + char const* name, + Fn fn, + CallPolicyOrDoc const& policy_or_doc, + char const* doc, + void const*) + { + typedef detail::def_helper helper; + + this->def_impl( + name, fn, helper::get_policy(policy_or_doc), helper::get_doc(policy_or_doc, doc), &fn); + + } + + template + void dispatch_def( + char const* name, + SigT sig, + StubsT const& stubs, + char const* doc, + detail::func_stubs_base const*) + { + // 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, *this, detail::get_signature(sig), doc); + } }; @@ -290,7 +316,7 @@ template inline void class_::register_() const { objects::register_class_from_python(); - + detail::register_copy_constructor( mpl::bool_t() , objects::select_holder((held_type*)0).get() diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 7ee7b188..012aee6d 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -14,6 +14,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -32,34 +34,62 @@ class module : public detail::module_base this->module_base::setattr_doc(name, python::object(x), 0); return *this; } - + module& add(type_handle x); // just use the type's name - + template module& add(class_ const& c) { // Soon to disappear... return *this; } - + template module& def(char const* name, Fn fn) { this->setattr_doc( name, boost::python::make_function(fn), 0); - + return *this; } + + template + module& def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0) + { + dispatch_def(name, arg1, arg2, doc, &arg2); + return *this; + } + + private: + template - module& def(char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0) + void + dispatch_def( + char const* name, + Fn fn, + CallPolicyOrDoc const& policy_or_doc, + char const* doc, + void const*) { typedef detail::def_helper helper; - + this->setattr_doc( name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)), helper::get_doc(policy_or_doc, doc)); - - return *this; + } + + template + void + dispatch_def( + char const* name, + SigT sig, + StubsT const& stubs, + char const* doc, + detail::func_stubs_base const*) + { + // 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, *this, detail::get_signature(sig), doc); } }; diff --git a/test/Jamfile b/test/Jamfile index fe0c7261..6ca688a2 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -14,7 +14,7 @@ local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; rule bpl-test ( name ? : files * ) { files ?= $(name).py $(name).cpp ; - + local modules ; local py ; for local f in $(files) @@ -28,7 +28,7 @@ rule bpl-test ( name ? : files * ) py = $(f) ; } } - + name ?= $(py:S=) ; for local f in $(files) @@ -36,11 +36,11 @@ rule bpl-test ( name ? : files * ) if $(f:S) != .py { local m = $(f:S=) ; - + if $(m) = $(py:S=) { m = $(name) ; - + if $(m) = $(py:S=) { m = $(m)_ext ; @@ -50,7 +50,7 @@ rule bpl-test ( name ? : files * ) modules += $(m) ; } } - + boost-python-runtest $(name) : $(py) $(modules) ; } @@ -63,6 +63,7 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters bpl-test test_pointer_adoption ; bpl-test operators ; bpl-test callbacks ; +bpl-test defaults_ext : defaults.py defaults.cpp ; bpl-test object ; bpl-test list ; @@ -123,7 +124,7 @@ run upcast.cpp ../../test/build/test_exec_monitor run select_holder.cpp ../../test/build/test_exec_monitor : # command-line args : # input files - : $(UNIT_TEST_PROPERTIES) + : $(UNIT_TEST_PROPERTIES) ;